java - 为什么无法在 Java 中使用 if 语句构建二进制信号量
问题描述
我有一个小问题,让我有点困惑。
这是我的代码:
public synchronized void P() {
while(!_state) {
this.wait();
}
_state = false;
}
此方法负责获取信号量。为什么不能用if
语句而不是while
循环来构建二进制信号量?
甲骨文文档说:
首先,同一对象上的同步方法的两次调用不可能交错。当一个线程正在为一个对象执行同步方法时,所有其他为同一对象调用同步方法的线程都会阻塞(暂停执行),直到第一个线程处理完该对象。
所以只有一个线程应该在 P() 方法内 -> 所以只有一个线程应该在 wait() 方法上被阻塞。其余线程应在 P() 方法级别上被阻止。但是当我更换它while()
时if()
它不能正常工作
解决方案
synchronized
方法相当于synchronized(this)
块。
只允许 1 个线程进入同步块。通过进入它,线程获取锁。当您wait
进入同步块时,您释放锁(对象监视器)并停放当前线程。此时,允许另一个线程进入该块。当其他线程将调用notify
或notifyAll
在被调用的同一对象上时,执行将继续wait
。当给定同步块的锁将被释放时,通知线程将“退出等待状态”。
总结一下 - 等待不会像你期望的那样工作,它不会阻塞执行,只会让等待线程进入睡眠状态,允许其他线程获取同步锁。
所以你不能做你想做的事,因为wait
工作方式与你期望的不同。你想在这里使用的是ReentrantLock
. https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html
推荐阅读
- python - 以这两种不同的方式创建信号有什么区别?
- java - 在按钮上单击我想切换 TextView 的文本
- numpy - numpy:为什么你会使用乘法而不是 matmul 进行矩阵乘法?
- python - python2中无限while循环中的事件处理
- c++ - 与 c++ 中 RGB 子字符串问题的框架逻辑相关的问题
- python - 如何在 macOS 上通过 pip 安装 Twilio 和其他库?
- excel - 使用来自另一个工作表的 500 多个列标题填充工作表的单元格
- javascript - 如何从标签中获取价值并将其价值每秒增加 1?
- sql - 在Oracle中使用分隔符从字符串中提取日期
- javascript - 在哪里从cordova应用上传文件以免费获取文件?