我正在得到java.lang.IllegalMonitorStateException
。我提到this问题,它解决了我的问题。第一个答案是
To be able to call notify() you need to synchronize on the same object.
synchronized (someObject) {
someObject.wait();
}
/* different thread / object */
synchronized (someObject) {
someObject.notify();
}
我的问题是为什么我们需要在同一个对象上同步以及它是如何工作的?
据我的理解,当我们说
synchronized (someObject) {
someObject.wait();
}
我们获得了对象 someObject 的锁,然后调用它的 wait() 。现在另一个线程如何获得同一个对象的锁定以对其调用notify()?我缺少什么?
为什么notify
也需要锁吗?
想象一下这个场景:
synchronized(x){
while(x.count < 4) {
x.wait();
//...
}
}
现在想象一下notify
其他地方没有任何锁:
//...
println(x.count); // print 3
x.count++;
if(count == 4)
x.notify()
//...
乍一看,整体听起来总是按预期工作。
然而,想象一下这种竞争条件:
//Thread1 enters here
synchronized(x){
while(x.count < 4) {
//condition is judged true and thread1 is about to wait
//..but..ohh!! Thread2 is prioritized just now !
//Thread2, acting on notify block side, notices that with its current count incrementation,
//count increases to 4 and therefore a notify is sent....
//but...but x is expected to wait now !!! for nothing maybe indefinitely !
x.wait();
//maybe block here indefinitely waiting for a notify that already occurred!
}
}
如果我们有办法告诉notify
side:
话题一:“嗯..notify
,你很可爱,但我才刚刚开始评估我的状况(x.count < 4
)为真,所以请...不要愚蠢地立即发送您期望的通知(在我将状态设置为等待之前),否则,我等待已经过去的事情将是荒谬的”
线程 2:“好吧好吧......我会在我的逻辑周围加锁以保持一致,以便我发送通知after您的等待调用释放了我们的共享锁,因此您将收到此通知,允许退出等待状态;)”
因此,始终在notify
一边,在被wait持有的同一个对象上,以避免这种情况,让关系始终一致。
=> 导致的逻辑notify
和导致的逻辑wait
永远不应该重叠。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)