等待方法唤醒而无需调用notify(NO SPURIOUS WAKEUP) [英] wait method wakes up without calling notify(NOT SPURIOUS WAKEUP)

查看:100
本文介绍了等待方法唤醒而无需调用notify(NO SPURIOUS WAKEUP)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的语句中,即使没有调用notify,也会执行wait()方法,但是语句below wait()仅在laurel线程完成执行后才执行.

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.

这次我尝试使用其他对象锁定hardy块的同步,等待方法仍然永远等待,有人可以解释为什么执行wait()之后的语句吗?

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();
    }
}

推荐答案

您无需假设虚假的唤醒来解释这里发生的情况.当月桂树终止时,它将向所有正在等待它的线程发送一个notifyAll. (这就是Thread.join的工作方式.)

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.)

有关Thread#join的信息,请参见API文档:

See the api doc for Thread#join:

此实现使用this.isAlive为条件的this.wait调用循环.当线程终止时,将调用this.notifyAll方法.建议应用程序不要在线程实例上使用wait,notify或notifyAll.

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.

此外,请始终使用条件在循环中等待;请参见Oracle并发教程,尤其是保护块"页面. (从描述中可以看到,join等待在被连接的线程上测试条件为isAlive的循环中进行循环,因此这是一个很好的示例.您可以在jdk源代码中找到Thread类的join方法.)

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.)

这篇关于等待方法唤醒而无需调用notify(NO SPURIOUS WAKEUP)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆