3 回答

TA贡献1796条经验 获得超7个赞
您不仅需要循环它,还需要检查循环中的条件。Java不能保证仅通过notify()/ notifyAll()调用或正确的notify()/ notifyAll()调用来唤醒您的线程。由于此属性,无环版本可能在您的开发环境上工作,而在生产环境上意外失败。
例如,您正在等待一些东西:
synchronized (theObjectYouAreWaitingOn) {
while (!carryOn) {
theObjectYouAreWaitingOn.wait();
}
}
邪恶的线程出现了:
theObjectYouAreWaitingOn.notifyAll();
如果邪恶线程没有/不能使carryOn您混乱,您只需继续等待适当的客户端。
编辑:添加了更多示例。等待可以中断。它抛出InterruptedException,您可能需要将等待包装在try-catch中。根据您的业务需求,您可以退出或取消该异常并继续等待。

TA贡献1851条经验 获得超5个赞
在Object.wait(long milis)的文档中得到了答复
线程也可以唤醒,而不会被通知,中断或超时,即所谓的虚假唤醒。尽管在实践中这种情况很少发生,但是应用程序必须通过测试应该导致线程唤醒的条件来防范它,并在条件不满足时继续等待。换句话说,等待应该总是像这样循环执行:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}
(有关此主题的更多信息,请参阅Doug Lea的“ Java并行编程(第二版)”(Addison-Wesley,2000年)中的3.2.3节,或Joshua Bloch的“有效的Java编程语言指南”(Addison-卫斯理,2001)。
添加回答
举报