我认为我已经知道了这个问题的答案,但是,我想阅读你的意见,以确保我真正理解java线程的状态机(或图表)是如何工作的。
想象一下,线程A在返回给定值之前运行 notify():
public class baz{
// Thread B runs this:
public synchronized void bar(){
wait();
}
// Thread A runs this:
public synchronized int foo(){
notify();
return 11;
}
}
在线程A释放锁定之前将调用notify()(这将发生在“返回11 ;语句之后”)。 那么,等待此锁定的线程B(通过 wait()方法)如何获取仍由线程A保持的锁定? 请注意,当通知线程B时,线程A尚未释放锁定。
所以我对这种情况的看法如下:
调用 wait()后,主题B会将其状态从正在运行更改为等待。 收到通知后(来自主题A notify()方法),主题B将从 wait()返回,将其状态更改为 Runnable ,试图获得锁定。由于线程A尚未释放锁定,因此线程B将在对象的监视器上被阻止,并将其状态从 Runnable 传递到阻止。 最后,在线程A释放锁定后,线程B将获得锁定并将其状态从阻止传递到正在运行。
这是对的吗?我想通过这个问题理解的是对从 wait()返回的线程发生了什么,该线程已经被已获取的锁同步。
答案 0 :(得分:1)
是的,你的解释是正确的。
当您在对象上调用wait()
时,调用线程将被添加到对象的wait set。当它为notify()
时,它将从该等待集中删除,并对该对象执行a lock action(它位于该对象的synchronized
块内)。该锁定动作将阻止当前线程直到它完成,即。锁定了对象监视器。
这与尝试在同一对象上输入synchronized
块时两个线程完全相同。要到达的第一个线程将锁定对象监视器,立即完成锁定对象。另一个线程阻塞直到其锁定动作完成,即。在第一个线程解锁显示器后。