1

尽管有很多关于这个主题的文章和 SO 帖子,但我仍然有一些疑问。所以请帮助我理解。说我写:

1.Class A(){}
 2.public static void main(String[] s){
 3. A obj= new A();
 4. synchronized(obj){ 
 5.       while(!condition)
 6.           obj.wait();
 7.  }
 8.}

现在根据解释,如果我们不使用同步块,从睡眠中唤醒的线程可能会丢失通知。但是第 6 行释放了对 obj 的锁定,即它的监视器由另一个线程拥有。现在,当该线程调用 notify() 时,由于 obj 的监视器不属于该线程,因此该线程如何得到通知。此外,第 4 行代码只执行一次,而不是在该线程的每个唤醒事件上执行。那么在等待()之前需要同步什么?

编辑:“第 4 行代码只执行一次”错误假设。同步块中的线程在从睡眠中恢复后重新获取锁,如答案中所述。谢谢

4

2 回答 2

1

它的工作原理与 javadoc 中的Object#wait解释一样,强调我的:

线程释放此监视器的所有权并等待,直到另一个线程通过调用 notify 方法或 notifyAll 方法通知在此对象的监视器上等待的线程唤醒。然后线程等待直到它可以重新获得监视器的所有权并恢复执行。

因此,一旦通知等待线程,它就会在继续执行下一条指令之前while(!condition)重新获取监视器(在您的情况下:) 。

于 2013-08-05T10:30:32.560 回答
0

“那么在等待()之前究竟需要同步什么?” :条件是跨线程共享的,条件的任何变化都应该是线程安全的,这就是同步的原因。这里的条件不是一些随机条件,但这是你的线程要等待的东西。希望这可以帮助。

于 2014-01-17T15:53:57.837 回答