Java:线程在对象上等待时是否释放所有监视器?

在线程可以wait对象之前,它必须获取该对象上的监视器。 然后释放监视器,一旦唤醒,线程就会尝试重新获取它。

但是当线程调用wait时,线程保持的其他监视器会发生什么?

考虑这个例子:

   对象a = // ...
   对象b = // ...

   同步(a)中
    {
       同步的(b)中
        {
            b.wait();
            //继续
        }
    }

当线程调用b.wait() ,它会释放ab上的锁,还是只释放b

只有b

这类问题的专制来源是Java语言规范。 本案例中的相关部分是17.8等待集和通知 :

让线程t在对象m上执行wait方法的线程,并且让nt on m上未被解锁操作匹配的锁定动作的数量。 发生以下操作之一。

  • […]
  • 否则,将发生以下序列:

    1. 线程t被添加到对象m的等待集中,并对m执行n次解锁动作。
    2. […]

从Object类的Java API文档:

当前线程必须拥有此对象的监视器。 该线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 然后线程等待,直到它可以重新获得监视器的所有权并继续执行。

因此,调用b.wait()仅释放b上的锁。

仅AFAIK b。 这是死锁的经典来源。