wait方法在没有调用notify的情况下醒来(不是懒散的唤醒)

时间:2017-05-19 18:13:32

标签: java multithreading

在下面的语句中,即使没有调用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();
    }
}

1 个答案:

答案 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方法。)