工作中的某个人刚刚询问了必须在同步中包装等待的原因.
老实说,我看不出推理.我理解javadocs所说的 - 线程需要成为对象监视器的所有者,但为什么呢?它会阻止哪些问题?(如果它确实是必要的,为什么等待方法不能获得监视器本身?)
我正在寻找一个相当深入的原因,或者可能是对文章的引用.我在快速谷歌中找不到一个.
哦,还有,thread.sleep如何比较?
编辑:很好的答案 - 我真的希望我可以选择不止一个,因为他们都帮助我理解发生了什么.
这里有很多好的答案.但是这里只想提一下,在使用wait()时,其他必须做的就是在一个循环中进行它,这取决于你正在等待的情况,以防你看到虚假的唤醒,这在我的经验确实发生过.
要等待其他某个线程将条件更改为true并通知:
synchronized(o) { while(! checkCondition()) { o.wait(); } }
当然,这些天,我建议只使用新的Condition对象,因为它更清晰,并且具有更多功能(例如允许每个锁具有多个条件,能够检查等待队列长度,更灵活的调度/中断等).
Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); lock.lock(); try { while (! checkCondition()) { condition.await(); } } finally { lock.unlock(); }
}
它需要拥有监视器,因为wait()的目的是释放监视器并让其他线程获取监视器来进行自己的处理.这些方法(wait/notify)的目的是协调对两个线程之间的同步代码块的访问,这两个线程需要彼此执行某些功能.这不仅仅是确保对数据结构的访问是线程安全的,而是协调多个线程之间的事件.
一个典型的例子是生产者/消费者案例,其中一个线程将数据推送到队列,另一个线程消耗数据.消费线程总是要求监视器访问队列,但是一旦队列为空,就会释放监视器.然后,当消费者不再处理时,生产者线程将只能访问该线程.一旦它将更多数据推入队列,它将通知消费者线程,因此它可以重新获得监视器并再次访问队列.
等待放弃显示器,所以你必须让它放弃.通知也必须有监视器.
你想要这样做的主要原因是确保你从wait()回来时有监视器 - 通常,你使用wait/notify协议来保护一些共享资源,你希望它是安全的等待返回时触摸它.与通知相同 - 通常您正在更改内容然后调用notify() - 您希望拥有监视器,进行更改并调用notify().
如果你做了这样的功能:
public void synchWait() { syncronized { wait(); } }
等待返回时你不会有显示器 - 你可以得到它,但你可能不会得到它.