在下面的语句中,即使没有调用notify也会执行wait()
方法,但语句below wait()
仅在laurel
线程完成执行后才执行。
我尝试使用其他对象来锁定hardy块的同步,这次等待方法仍在等待,有人可以解释为什么wait()
执行后的语句?
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();
}
}
答案 0 :(得分:3)
你不需要假设一个虚假的唤醒来解释这里发生了什么。当laurel终止时,它会向正在等待它的线程发送notifyAll。 (这就是Thread.join的工作原理。)
请参阅Thread #join的api doc:
此实现使用this.wait调用on.isAlive的循环。当一个线程终止时,将调用this.notifyAll方法。建议应用程序不要在Thread实例上使用wait,notify或notifyAll。
此外,总是在循环中等待,使用条件;请参阅Oracle并发教程,尤其是Guarded Blocks页面。 (从描述中你可以看到join在一个循环中等待,其中测试条件是isAlive在连接的线程上,所以这是一个很好的例子。你可以在Thread类的jdk源中找到join方法。)