Consider the following code
public class ThreadTest1
{
private static final long startTime = System.currentTimeMillis();
public static void main(String args[])
{
Thread ct = new Thread(new ChildThread());
ThreadTest1.print("starting child threads in MAIN");
ct.start();
synchronized(ct)
{
try
{
ThreadTest1.print("about to start wait() in MAIN");
ct.wait();
ThreadTest1.print("after wait() in MAIN");
}
catch(Exception e)
{
ThreadTest1.print("Exception in MAIN");
}
}
}
public static void print(String s)
{
System.out.println("Millisecond : "+(System.currentTimeMillis()-ThreadTest1.startTime)+"\t: "+s);
}
}
class ChildThread implements Runnable
{
public void run()
{
synchronized(this)
{
try
{
ThreadTest1.print("before thread notifyAll in CHILD");
notifyAll();
ThreadTest1.print("notifyAll over, sleep starts in CHILD");
Thread.sleep(10000);
ThreadTest1.print("after thread sleep in CHILD");
}
catch(Exception e)
{
ThreadTest1.print("Exception in CHILD");
}
ThreadTest1.print("End of run method in CHILD");
}
}
}
The ouput follows :
Millisecond : 12 : starting child threads in MAIN
Millisecond : 13 : about to start wait() in MAIN
Millisecond : 13 : before thread notifyAll in CHILD
Millisecond : 13 : notifyAll over, sleep starts in CHILD
Millisecond : 10015 : after thread sleep in CHILD
Millisecond : 10015 : End of run method in CHILD
Millisecond : 10016 : after wait() in MAIN
notifyAll() gets called at the 13th millisecond. But control comes out of wait() only at 10016th millisecond.
From the code given above, it appears as if the wait() call doesn't get over immediately after the notify() call.
But all documentations including the Java API, specify that the method calling wait() should get the lock immediately after the notify() call.
If wait() will not get over when notify() is called, then the need for notify() becomes void since the method calling wait() will automatically get control when the run method of the new thread gets over even if notify() is not called.
Waiting for someone to throw some light, if I am committing a mistake here.
With the suggestions of other answers, here is a working implementation. Note that I also moved the sleep outside of the
synchronized
block. As a rule, synchronized blocks should always be as short as possible ...