Java:线程在对象上等待时是否释放所有监视器?
在线程可以wait
对象之前,它必须获取该对象上的监视器。 然后释放监视器,一旦唤醒,线程就会尝试重新获取它。
但是当线程调用wait
时,线程保持的其他监视器会发生什么?
考虑这个例子:
对象a = // ... 对象b = // ... 同步(a)中 { 同步的(b)中 { b.wait(); //继续 } }
当线程调用b.wait()
,它会释放a
和b
上的锁,还是只释放b
?
只有b
。
这类问题的专制来源是Java语言规范。 本案例中的相关部分是17.8等待集和通知 :
让线程t是在对象m上执行wait方法的线程,并且让n是t on m上未被解锁操作匹配的锁定动作的数量。 发生以下操作之一。
- […]
否则,将发生以下序列:
- 线程t被添加到对象m的等待集中,并对m执行n次解锁动作。
- […]
从Object类的Java API文档:
当前线程必须拥有此对象的监视器。 该线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
因此,调用b.wait()
仅释放b
上的锁。
仅AFAIK b。 这是死锁的经典来源。