wait() 如何在 Java 中恢复 Lock

这是一个提倡的范例,即 wait() 应该在同步块内的 while 循环中调用。

我的问题是等待()线程如何取回锁?

// Thread 1
    synchronized (mon) {
     while (!condition) 
          mon.wait();

    // Do something
    }

//Thread 2
    synchronized (mon) {//set condition appropriately
            mon.notify();
    }

假设线程 1 首先运行并开始等待条件。它释放锁,线程 2 获取锁设置条件并通知线程 1。现在线程 1 获取锁,检查条件并开始执行“执行某些操作”。

我的问题是,当线程1被通知时,它从while条件开始执行,具有Synced(mon)的代码行永远不会再次执行,然后线程1如何获取锁定?将锁送回线程 1 的内部动态是什么?


答案 1

当 Thread1 收到通知时,线程必须先获取锁,然后才能退出 wait 方法,请参阅 Object#wait 的 java 文档:

然后,从此对象的等待集中删除该线程,并重新启用线程调度。然后,它以通常的方式与其他线程竞争在对象上同步的权利;一旦它获得了对对象的控制,它对该对象的所有同步声明都将恢复到原状 - 即,恢复到调用该方法时的情况。然后,线程从方法的调用返回。因此,从方法返回时,对象和线程的同步状态与调用方法时完全相同。TwaitTwaitwaitTwait


答案 2

synchronized(mon)不是必须执行的表达式。

它是源代码中的一个语法元素,它告诉编译器(然后是运行时),只有在当前线程获取了与 关联的锁之后,才能执行代码的包装部分,即使您不是“来自”同步块之前的代码行。mon

wait()释放锁,并且必须在返回之前重新获取锁。