这是一个倡导的范例,应该在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的内部动态是什么?
答案 0 :(得分:8)
当Thread1被通知时,线程必须获取锁才能退出wait方法,请参阅java doc for Object#wait:
然后从等待集中删除线程
T
对象并重新启用线程调度。然后它竞争 通常的方式与其他线程的权利同步 宾语;一旦它获得了对象的控制权,所有它 对象的同步声明恢复到现状 赌注 - 也就是说wait
时的情况 方法被调用。线程T
然后从 调用wait
方法。因此,从...返回wait
方法,对象和线程的同步状态T
与wait
方法完全相同 调用
答案 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方法时完全一样。”我是对的吗?