Java:当线程等待对象时,所有监视器都会被释放吗?

2022-09-02 09:31:51

在线程可以对对象进行操作之前,它必须在该对象上获取监视器。然后释放监视器,线程在唤醒后尝试重新获取它。wait

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

请考虑以下示例:

   Object a = // ...
   Object b = // ...

   synchronized(a)
   {
       synchronized(b)
       {
           b.wait();
           // continue
       }
   }

当线程调用时,它会在 and 和 上释放锁,还是只释放锁?b.wait()abb


答案 1

只。b

这类问题的唯权主义来源是Java语言规范。本例中的相关部分是 17.8 等待集和通知

设 thread t 是在对象 m 上执行 wait 方法的线程,并设 ntm 上未与解锁操作匹配的锁定操作数。将发生下列操作之一。

  • [...]
  • 否则,将出现以下序列:

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

答案 2

Object 类的 Java API 文档中:

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

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