我想我已经知道了那个问题的答案,但是,我想阅读您的意见以确保我真正理解 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;
}
}
notify() 将在线程 A 释放锁之前调用(这将在 return 11; 语句“之后”发生)。 那么,正在等待此锁(通过 wait() 方法)的线程 B 如何获取仍由线程 A 持有的锁? 请注意,当线程 B 收到通知时,锁尚未被线程 A 释放。
所以我对这种情况的看法是:
调用wait()后,线程B的状态将从Running变为Waiting。 在收到通知后(来自线程 A notify() 方法),线程 B 将从 wait() 返回,将其状态更改为 Runnable 并且尝试获取锁。由于锁尚未被线程 A 释放,线程 B 将在对象的监视器上被阻塞,并将其状态从 Runnable 传递到 Blocked。 最终,在线程 A 释放锁后,线程 B 将获取锁并将其状态从Blocked 变为Running。
这样对吗?对于这个问题,我想了解的是 发生了什么 从 wait() 返回的线程,该线程由已获取的锁同步。
最佳答案
是的,你的解释是正确的。
当您在对象上调用wait()
时,调用线程将被添加到对象的wait set 中。 .当它被 notify()
ied 时,它将被从那个等待集中移除,并执行 a lock action在对象上(它在该对象的 synchronized
block 中)。该锁定操作将阻塞当前线程,直到它完成为止,即。锁定对象监视器。
这与两个线程在同一对象上尝试进入 synchronized
block 时的行为完全相同。第一个到达的线程将锁定对象监视器,立即完成锁定对象。另一个线程阻塞,直到其锁定操作完成,即。在第一个线程解锁监视器之后。
关于java:如果总是在锁释放之前调用 notify(),等待的线程如何获得同一个锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26701869/