为什么我们需要在同一个对象上同步以使notify()工作 [英] Why do we need to synchronize on the same object for notify() to work

查看:105
本文介绍了为什么我们需要在同一个对象上同步以使notify()工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到 java.lang.IllegalMonitorStateException 。我提到了这个问题,它解决了我的问题。第一个答案是

I was getting java.lang.IllegalMonitorStateException. I referred this question and it solved my problem. The first answer is

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()?我缺少什么?

we get a lock on object someObject and then we call wait() on it. Now how can another thread get lock on same object to call notify() on it? What am I missing?

推荐答案

为什么通知也需要锁?

Why does notify need a lock too?

想象一下场景:

synchronized(x){
        while(x.count < 4) {
          x.wait();
          //...
        }
}

想象一下a 通知其他地方没有任何锁定:

Imagine now a notify elsewhere without any lock around it:

//...
println(x.count); // print 3
x.count++;
if(count == 4) 
  x.notify()
//...

乍一看,整个声音始终按预期工作。

然而,想象一下这种竞争条件:

At first glance, the whole sounds to always work as expected.
However, imagine this race condition:

//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!
     }
}

如果我们有办法告诉这个通知方:

If only we had a way to tell this to notify side:

主题1:Humm .. 通知,你很可爱,但我刚开始评估我的情况( x.count< 4 )为真,所以请...不要愚蠢刚刚发送你的预期通知(在我将状态等待之前),否则,等待已经过去的事情我会很荒谬

Thread 1: "Humm..notify, you are cute but I've just started to evaluate my condition (x.count < 4) to true, so please... don't be silly by sending your expected notification just now (before I put my status to waiting), otherwise, I would be ridiculous to wait for a thing that already passed"

线程2:好的好的...为了保持一致,我会锁定我的逻辑,以便我在等待调用后发送通知释放我们的共享锁,因此您将收到此通知,允许退出你的等待状态;)

Thread2: "Ok ok... I will put a lock around my logic in order to stay consistent, so that I send my notification after your wait call releases our shared lock, and thus you will receive this notif, allowing to quit your waiting status ;)"

因此,总是在同一个对象上的 notify 侧锁定这是等待,以避免这种情况,让关系始终保持一致。

Thus, always place a lock on the notify side, on the same object that is hold by wait, in order to avoid this situation and let the relationship always consistent.

=>导致通知的逻辑和导致等待不应该重叠。

=> A logic leading to a notify and a logic leading to a wait should never overlap.

这篇关于为什么我们需要在同一个对象上同步以使notify()工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆