14

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

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

// 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 条件开始执行时,具有 Synchronized(mon) 的代码行不再执行,那么线程 1 如何获取锁?将锁定返回给 Thread 1 的内部动态是什么?

4

4 回答 4

8

当 Thread1 被通知线程必须获得锁才能退出等待方法时,请参阅 Object#wait 的 java 文档:

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

于 2013-05-26T15:09:17.573 回答
7

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

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

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

于 2013-05-26T15:09:30.303 回答
0

线程 1 收到通知后,立即获得锁并开始运行//Do something

Thread 1 等待时,只是暂时释放锁,当线程收到通知后,可以再次获取锁,无需运行 synchronized(...)。

于 2013-05-26T15:16:05.370 回答
0
// Thread 1
 synchronized (mon) {
 Systemout.println("I am invoked!");
 while (!condition) 
      mon.wait();

// Do something
}

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

在原始场景中:考虑线程 1 首先运行并开始等待条件。它释放锁,线程 2 获得锁设置条件并通知线程 1。现在线程 1 获得锁,检查条件并开始执行“做某事”。

如果我正确理解以下内容:

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

Systemout.println("我被调用了!"); 不会执行,因为“因此,从等待方法返回时,对象和线程 T 的同步状态与调用等待方法时完全相同。”

我对吗?

于 2013-11-08T08:45:26.603 回答