java - 如果我(需要)将 wait() 和 notify() 调用包含在同步块(synchronized block)中,那么如何执行 notify()?

标签 java multithreading concurrency

我以为我会理解 Java 中的并发概念,但现在有一件事打破了我的理解:

为什么我必须在同步块(synchronized block)中包含对 wait() 和 notify() 方法的调用?

假设我有两个线程:线程 A 和线程 B。我还有一个对象将用作锁。 现在在某个时间点,线程 A 调用对象上的 wait(),然后被阻塞,直到其他线程调用同一对象上的 notify()。到目前为止,这是我的理解,这很好。但现在它说我需要将这些调用包含在此对象上同步的 block 中 - 事实上,如果我不这样做,我会得到一个 IllegalMonitorStateException。如果我添加这些 block ,它工作正常 - 但为什么呢??

我本以为,如果我使用这些同步块(synchronized block),那么线程 A 将永远保持对对象的锁定,因为 wait() 方法继续运行而线程 B 只是不能执行 notify(),因为它无法获取对象上的锁,因为它仍由线程 A 拥有。

然而,正如我所说,实际上它工作正常,线程 B 可以执行 notify() 来解除线程 A 的阻塞……有人可以向我解释一下这里到底发生了什么吗?线程 B 如何获取锁?

最佳答案

如何

当你在synchronized block 中调用wait 时,监视器锁会自动释放,参见doc :

The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

在另一个线程调用notify 并退出其synchronized block 后,等待线程将被唤醒并尝试获取监视器锁以继续。

为什么

简要说明:

A wait() only makes sense when there is also a notify(), so it's always about communication between threads, and that needs synchronization to work correctly.

检查 this了解更多。

关于java - 如果我(需要)将 wait() 和 notify() 调用包含在同步块(synchronized block)中,那么如何执行 notify()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48963547/

相关文章:

mysql - Passenger Nginx 如何处理并发请求

java - 创建后通过方法加载对象的数据,还是直接获取加载数据的实例化对象?

java - 从 Wildfly 连接到 TibcoJMS 服务器

android - SurfaceView 实现 Runnable - 线程不启动

c - 服务器中的 Leader/Follower pthread 实现

go - 等待完成后我们是否需要创建新的 WaitGroup ?

java - Java 8 流是原子的吗?

Java自定义注解查找方法

java - 创建 android 项目时出错 Ionic 平台 android

Java jdbc Sql Server 并行写入