Java - notifyAll()和notify()失败了吗?可能吗?

时间:2012-02-14 08:13:10

标签: java

这对我来说真的很奇怪,但看起来我的程序中的notifyAll()/ notify()失败了。 代码相当复杂,基本上我有三个线程A,B,C

向B发送请求并在请求上发出wait()并超时10秒,当B完成时,它会调用notify()来唤醒A。

在死环中的C通过队列向A提供大量字符串,A拾取并打印出来。每次A打印出一个字符串,它就会向B发送请求并等待。

因此工作流程变为:

C继续为死环提供食物

  1. A打印出来自C
  2. 的字符串
  3. 向B发送请求并等待(10)
  4. B notify()A ......

  5. A从C打印出字符串 ....一次又一次....

  6. 这可以在几秒钟内完成。然而,过了一会儿我看到B打印出来它已经通知()A,A仍然在等待,因为C用来喂A的队列快速增加,并且没有字符串被A打印。最后,10秒后,A抱怨请求超时。

    这看起来像notify()失败,因为B在调用notify()之后打印出消息。鉴于wait / notify是java的根本特性,我不敢相信它会失败。有可能吗?

1 个答案:

答案 0 :(得分:2)

notify()仅在当时有一个线程wait()时才会起作用。

您应该使用的习惯用法是更改与notify()/ notifyAll()相同的同步块中的状态。在等待块中,您反复检查状态更改。这样,如果过早触发通知,则会记录状态更改。此外,如果等待虚假地等待,如果状态没有改变,它将再次等待。

public synchronized void notifyReady() {
    ready = true;
    notifyAll();
}

public synchronized void waitForReady() throws InterruptedException {
    while(!ready)
      wait();
}