Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Output of a Java program

I am trying to run a program where I have created 3 threads.

1) Apple.Java

package Test;
import java.util.Random;

public class Apple implements Runnable{

    String name;
    int time;
    Random r = new Random();

    public Apple(String s){

        name = s;
        time = r.nextInt(999);
    }

    public void run(){

        try{
            System.out.printf("%s is sleeping for %d\n", name, time);
            //because we want each thread to sleep for random time.
            Thread.sleep(time);
            System.out.printf("%s is done\n" + name);

        }catch(Exception e){}
    }
}

2) ThreadTest.java

package Test;

public class Anand {

    public static void main(String[] args){

        Thread t1 = new Thread(new Apple("one"));
        Thread t2 = new Thread(new Apple("two"));
        Thread t3 = new Thread(new Apple("three"));
        t1.start();
        t2.start();
        t3.start();
    }
}

Expected output is

one is sleeping for 934
three is sleeping for 383
two is sleeping for 228
two is done.
three is done.
one is done.

Actual output is :

When I am running "ABC.java" as Java application I am getting following output :

one is sleeping for 934
three is sleeping for 383
two is sleeping for 228

Here I am not able to understand why below statement is not getting executed? or why i am not getting output of the below statement on console?

 System.out.printf("%s is done\n" + name);
like image 909
Curious Techie Avatar asked May 02 '26 23:05

Curious Techie


2 Answers

The actual bug in this code is:

java.util.MissingFormatArgumentException: Format specifier '%s'

ideone demo

Because this:

System.out.printf("%s is done\n" + name);

should be:

System.out.printf("%s is done\n", name);

Please consider this be an illustrative example of why empty catch blocks should rarely (if ever) be used.

}catch(Exception e){}  // Aaaargh! Nope nope nope.

At a minimum, print the stack trace:

}catch(Exception e){
  e.printStackTrace();
}

But also, make sure that you wait for the threads to complete:

t1.join();
t2.join();
t3.join();

This is more of a good habit (akin to closing streams) than something necessary for this particular example.

From the Javadoc of Thread:

The Java Virtual Machine continues to execute threads until either of the following occurs:

  • The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
  • All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

OP's code doesn't invoke exit, so that's not relevant here. All of the threads are non-daemon threads, so execution will continue until they've all finished (somehow). In other words, the JVM will implicitly inserts a join() to wait for all threads to complete. As such, only inserting a join, as suggested in other answers, doesn't actually do anything to change the behavior of the code.

like image 56
Andy Turner Avatar answered May 05 '26 14:05

Andy Turner


System.out.printf("%s is done\n" + name);

replace the above line with System.out.printf("%s is done\n" , name);

Now it will work.

like image 22
saidi reddy Avatar answered May 05 '26 13:05

saidi reddy