为什么必须等待()始终处于同步块

问题:

我们都知道为了调用Object.wait(),这个调用必须被置于同步块中,否则抛出IllegalMonitorStateException。但什么原因造成这种限制?我知道wait()发布监视器,但是为什么我们需要通过使特定的块同步来明确地获取监视器,然后通过调用wait()释放监视器
如果可以在同步块外调用wait(),保留其语义 – 挂起调用者线程,那么潜在的损害是甚么?

回答:

notify()还有notify()时,wait()也是有意义的,所以它总是关于线程之间的通信,并且需要同步才能正常工作。人们可以认为这应该是隐含的,但这不是真正的帮助,原因如下:
从语法上讲,你从来没有wait()。你需要一些条件来被服从,如果不是,你等到它是。所以你真正做的是

if(!condition){
    wait();
}

但条件是由一个单独的线程设置,所以为了使这个工作正常,你需要同步。
几个更多的事情错了,它只是因为你的线程退出等待并不意味着你正在寻找的条件是真的:

  • 你可以得到虚假的唤醒(这意味着一个线程可以从等待中唤醒,没有收到通知),或者
  • 条件可以设置,但是第三个线程在等待线程唤醒(并重新获取监视器)时再次使条件为false。

为了处理这些情况,您真正需要的是always一些变体:

synchronized(lock){
    while(!condition){
        lock.wait();
    }
}

更好的是,不要混淆同步原语,并使用java.util.concurrent包中提供的抽象。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Why must wait() always be in synchronized block

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

5 + 1 =