java:如果总是在锁释放之前调用 notify(),等待的线程如何获得同一个锁?

标签 java multithreading

我想我已经知道了那个问题的答案,但是,我想阅读您的意见以确保我真正理解 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/

相关文章:

java - 如何将返回的 JSON 数据放入 HTML 表单中

java - AtomicInteger 似乎不适合我

java - 在 Quasar 中调度任务,无需生成新线程

java - BufferedImage + jPanel 使用 Qt 在 C++ 中查看图像的等效方法

java - 在maven fork进程执行期间只运行一次代码?

java - @JsonIgnore 不起作用

c - 线程安全变量 comaprison C VS2010

java:广度优先遍历迷宫回溯

java - 线程/处理程序错误 - 尚未发布指定的消息队列同步屏障 token

java - 我怎么知道哪个线程调用了我的 Log 方法?