Java为什么必须wait()始终处于同步块中

我们都知道,为了调用Object.wait(),必须将此调用放置在同步块中,否则将IllegalMonitorStateException引发。但是,进行此限制的原因是什么?我知道这wait()释放了监视器,但是为什么我们需要通过使特定的块同步来显式获取监视器,然后通过调用来释放监视器wait()

如果可以wait()在同步块之外调用并保留其语义-挂起调用者线程,可能造成什么损害?

回答:

wait()只有在还存在时,A才有意义notify(),因此它始终与线程之间的通信有关,并且需要同步才能正常工作。有人可能会争辩说这应该是隐式的,但这并没有真正的帮助,原因如下:

从语义上讲,你永远不会wait()。你需要满足一些条件,如果不是,请等到满足。所以你真正要做的是

if(!condition){

wait();

}

但是条件是由单独的线程设置的,因此为了正确执行此工作,你需要同步。

还有其他一些问题,仅仅是因为线程退出等待并不意味着你要寻找的条件是正确的:

你可能会得到虚假的唤醒(这意味着线程可以从等待中唤醒而从未收到通知),或者

可以设置条件,但是第三个线程在等待线程唤醒(并重新获取监视器)时再次使条件变为假。

为了处理这些情况,你真正需要的始终是这种变化:

synchronized(lock){

while(!condition){

lock.wait();

}

}

更好的是,根本不要弄乱同步原语,而要使用java.util.concurrent软件包中提供的抽象。

以上是 Java为什么必须wait()始终处于同步块中 的全部内容, 来源链接: utcz.com/qa/423747.html

回到顶部