这对我来说真的很奇怪,但看起来我的程序中的notifyAll()/ notify()失败了。 代码相当复杂,基本上我有三个线程A,B,C
向B发送请求并在请求上发出wait()并超时10秒,当B完成时,它会调用notify()来唤醒A。
在死环中的C通过队列向A提供大量字符串,A拾取并打印出来。每次A打印出一个字符串,它就会向B发送请求并等待。
因此工作流程变为:
C继续为死环提供食物
B notify()A ......
A从C打印出字符串 ....一次又一次....
这可以在几秒钟内完成。然而,过了一会儿我看到B打印出来它已经通知()A,A仍然在等待,因为C用来喂A的队列快速增加,并且没有字符串被A打印。最后,10秒后,A抱怨请求超时。
这看起来像notify()失败,因为B在调用notify()之后打印出消息。鉴于wait / notify是java的根本特性,我不敢相信它会失败。有可能吗?
答案 0 :(得分:2)
notify()仅在当时有一个线程wait()时才会起作用。
您应该使用的习惯用法是更改与notify()/ notifyAll()相同的同步块中的状态。在等待块中,您反复检查状态更改。这样,如果过早触发通知,则会记录状态更改。此外,如果等待虚假地等待,如果状态没有改变,它将再次等待。
public synchronized void notifyReady() {
ready = true;
notifyAll();
}
public synchronized void waitForReady() throws InterruptedException {
while(!ready)
wait();
}