【问题标题】:Why method wait() works without notify()?为什么方法 wait() 在没有 notify() 的情况下工作?
【发布时间】:2014-03-28 16:55:26
【问题描述】:

非常感谢!

我在同步 2 个线程时遇到了问题:主线程和从 StepRunner.java 调用的线程。我只需要在下一次迭代开始之前显示迭代结果。

我想要什么:

Please enter step number [1, 2, 3 or 4] or 5 for exit: 2
Please enter natural value for factorial computing: 2
2! = 2
Please enter step number [1, 2, 3 or 4] or 5 for exit:

我不想要的:

Please enter step number [1, 2, 3 or 4] or 5 for exit: 2
Please enter natural value for factorial computing: 2
Please enter step number [1, 2, 3 or 4] or 5 for exit: 2! = 2

为此,我在 StepRunner.java 中有同步块:

public void run() {
        thread.start();
        synchronized (thread) {
            try {
                while (thread.isAlive()) { /**Loop is an Oracle's recommendation*/
                    thread.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

但是为什么方法 wait() 在我的代码的任何地方没有方法 notify() 也能正常工作?

【问题讨论】:

  • 您是否检查过循环是否已执行?这只是一个猜测,但也许线程拥有自己的监视器(或者调度程序拥有),因此同步块仅在线程完成后执行并且不再活跃。
  • 当线程死亡时它会通知自己。

标签: java multithreading reflection wait notify


【解决方案1】:

Thread's javadoc 声明Thread.notifyAll() 在线程完成时在内部被调用:

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

如您所见,不建议使用此功能,您的代码可以改写如下:

thread.start();
try {
    thread.join();    
} catch (InterruptedException e) {
    e.printStackTrace();
}

鉴于此语句仅出现在 Java 7 javadoc 中,建议不要使用此功能,看起来此行为曾经是 Thread 类的实现细节,但人们开始依赖它,所以该语言作者必须记录它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2019-07-03
    • 1970-01-01
    相关资源
    最近更新 更多