wait()如何在Java中获取Lock

时间:2013-05-26 15:04:05

标签: java multithreading synchronization locking wait

这是一个倡导的范例,应该在synchronized块内的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如何获取锁定?将锁定回到线程1的内部动态是什么?

4 个答案:

答案 0 :(得分:8)

当Thread1被通知时,线程必须获取锁才能退出wait方法,请参阅java doc for Object#wait:

  

然后从等待集中删除线程T   对象并重新启用线程调度。然后它竞争   通常的方式与其他线程的权利同步   宾语;一旦它获得了对象的控制权,所有它   对象的同步声明恢复到现状   赌注 - 也就是说wait时的情况   方法被调用。线程T然后从   调用wait方法。因此,从...返回   wait方法,对象和线程的同步状态   Twait方法完全相同   调用

答案 1 :(得分:7)

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

源代码中的语法元素告诉编译器(然后是运行时)代码的包装部分必须仅在当前线程获取与mon关联的锁之后执行,即使你没有“来自”同步块之前的代码行。

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

答案 2 :(得分:0)

在通知线程1后,它立即获得锁定并开始运行 //执行某些操作

当线程1等待时,它只是暂时释放锁定,当线程被通知时,它可以再次获得锁定而不需要运行synchronized(...)。

答案 3 :(得分: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并重新启用线程调度。然后它以通常的方式与其他线程竞争,以便在对象上进行同步;一旦它获得了对象的控制权,它在对象上的所有同步声明都将恢复到原状 - 即,调用wait方法时的情况。线程T然后从wait方法的调用返回。因此,从wait方法返回时,对象和线程T的同步状态与调用wait方法时的状态完全相同。

这条线      Systemout.println(“我被调用!”); 将执行,因为“因此,从wait方法返回时,对象和线程T的同步状态与调用wait方法时完全一样。”

我是对的吗?