Reputation: 59
In the statement below, the wait()
method is executed even though no notify is called but the statement below wait()
are executing only after laurel
thread completes its execution.
I tried using other objects for locking in synchronization of hardy block this time wait method is still waiting forever, can someone explain me why statement after wait()
was executed?
package delagation;
public class Solution extends Thread {
static Thread laurel, hardy;
public static void main(String[] args) throws InterruptedException {
laurel = new Thread() {
public void run() {
System.out.println("A");
try {
hardy.sleep(1000);
} catch (Exception e) {
System.out.println("B");
}
System.out.println("C");
}
};
hardy = new Thread() {
public void run() {
System.out.println("D");
try {
synchronized(laurel) {
laurel.wait();
//wait method is called here,
//There is not notify in this class,
//but the statement below are executing
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {
System.out.println("E");
}
System.out.println("F");
}
};
laurel.setName("laurel");
hardy.setName("hardy");
laurel.start();
hardy.start();
}
}
Upvotes: 4
Views: 516
Reputation: 96434
You don't need to postulate a spurious wakeup to explain what's going on here. When laurel terminates it sends a notifyAll to the threads that are waiting on it. (This is how Thread.join works.)
See the api doc for Thread#join:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Also, always wait in a loop, using a condition; see the Oracle concurrency tutorial, especially the Guarded Blocks page. (From the description you can see join waits in a loop where the tested condition is isAlive on the thread joined to, so it is s good example. You can find the join method in the jdk source for the Thread class.)
Upvotes: 4