java - 当线程进入 Java 中的同步块(synchronized block)/方法时到底发生了什么

标签 java multithreading synchronized

我很好奇当我的线程到达同步块(synchronized block)并阻塞监视器时到底发生了什么。

它实际上是否在所有其他尝试使用此监视器的线程上隐式调用 wait()?或者监视器有一些正在更改的特定标志?

另外,当我们跳出同步块(synchronized block)时会发生什么?它会以某种方式为当前监视器调用 notify 或 notifyAll 吗?

我真的很纠结这个。

最佳答案

我认为最好从底层同步原语的角度来思考:Java 监视器是一个互斥体,同步块(synchronized block)是一个区域,其中互斥体在 { 上锁定并在 上解锁} 和 wait、notify 和 notifyAll 是在与互斥体关联的条件变量上调用的方法。

要记住的重要一点是,当 wait() 被调用时,互斥锁可以在同步块(synchronized block)中解锁,因为 wait 将解锁互斥锁并阻塞,直到 notify 或 notifyAll被称为

因此,尽管推断这是不可能的,但多个线程仍然可以在同步块(synchronized block)中被阻塞。

更新:带注释的代码演示了这一点:

Object lock;
// ...
synchronized (lock) { // Underlying mutex is locked.
    // ...
    lock.wait(); // Unlocks mutex, blocks until notify, relocks mutex
    // ...
} // Underlying mutex unlocked

一旦 lock.wait() 被调用,其他线程就可以自由进入同步块(synchronized block)。它们也会阻塞,直到 lock.notify()lock.notifyAll() 唤醒它们。

关于java - 当线程进入 Java 中的同步块(synchronized block)/方法时到底发生了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32871933/

相关文章:

使用 Frame 进行 Python 多处理

c# - 线程退出时如何处理 ThreadLocal 值?

java - 使用 waitFor() 的程序无法像在 Windows 上那样在 Linux 上运行

Java 同步方法 - OCPJP

java - 为什么这个程序中同一个对象没有死锁 - Java 多线程

java - 为什么 JUnit 测试异常总是失败?

java - 制作带有部分的编辑器页面不起作用(eclipse,java)

java - Java Swing 应用程序中的希腊语/拉丁语科学 JLabel

java - 如何使用数据库中的动态数据显示多个页面?

c++ - 如何在C++ Windows 7下启动/停止WAV声音