为了账号安全,请及时绑定邮箱和手机立即绑定

为什么总是在循环内调用wait()

为什么总是在循环内调用wait()

慕少森 2019-10-08 11:25:13
我读过,我们应该始终wait()在循环内调用a :while (!condition) { obj.wait(); }它可以正常工作而没有循环,那为什么呢?
查看完整描述

3 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

您不仅需要循环它,还需要检查循环中的条件。Java不能保证仅通过notify()/ notifyAll()调用或正确的notify()/ notifyAll()调用来唤醒您的线程。由于此属性,无环版本可能在您的开发环境上工作,而在生产环境上意外失败。


例如,您正在等待一些东西:


synchronized (theObjectYouAreWaitingOn) {

   while (!carryOn) {

      theObjectYouAreWaitingOn.wait();

   }

}

邪恶的线程出现了:


theObjectYouAreWaitingOn.notifyAll();

如果邪恶线程没有/不能使carryOn您混乱,您只需继续等待适当的客户端。


编辑:添加了更多示例。等待可以中断。它抛出InterruptedException,您可能需要将等待包装在try-catch中。根据您的业务需求,您可以退出或取消该异常并继续等待。


查看完整回答
反对 回复 2019-10-08
?
江户川乱折腾

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


查看完整回答
反对 回复 2019-10-08
  • 3 回答
  • 0 关注
  • 589 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信