java - Java - Dekkers 算法实现导致临界区中有两个线程
问题描述
我正在尝试为有两条铁路的场景实施 Dekkers 算法,并且有一点它们都使用轨道的同一部分。一次只能允许一列火车进入该部分,并且一列火车可以连续通过任意次数,除非其他火车都在转弯并且准备通过。
下面是我为第一条铁轨实现的代码。
while (allowed) {
choochoo();
setWantToUseTrack(0,true);
while (getWantToUseTrack(1)) {
if (getTurn() != 0) {
setWantToUseTrack(0,false);
while (getTurn() != 0) {
//wait loop
}
setWantToUseTrack(0, true);
}
}
//critical section starts
crossPass();
//critical section ends
setTurn(1);
setWantToUseTrack(0,false);
}
}
下面是我实现第二条铁路的代码。
while (allowed) {
choochoo();
setWantToUseTrack(1,true);
while (getWantToUseTrack(0)) {
if (getTurn() != 1) {
setWantToUseTrack(1,false);
while (getTurn() != 1) {
//wait loop
}
setWantToUseTrack(1,true);
}
}
//critical section starts
crossPass();
//critical section ends
setTurn(0);
setWantToUseTrack(1,false);
}
当这段代码运行时,有时两列火车会同时进入临界区。我看不到逻辑错误。我在我的实施中遗漏了什么吗?
解决方案
可能会发生以下情况(仅一个示例):
- 在第二个轨道
setWantToUseTrack(1,false);
被调用。 在第一个跟踪谓词被检查:
while (getWantToUseTrack(1))
,到第二个线程没有停止在while
循环中。这是绝对可行的,因为第一个轨道可以在
choochoo();
(1.) 之前停止,而第二个轨道可以在 (2.) 发生之前停止。- 方法
getWantToUseTrack
返回false
0 和 1。
创建一个循环来捕获线程直到关键部分被释放是有点危险的。您可能希望通过使用synchronized
with crossPass
definition 使部分线程安全。
推荐阅读
- ios - 基于天解锁内容(带有 Xcode 的 iOS 应用程序)
- javascript - Async/await - 等待函数和非等待函数的组合
- algorithm - 计算唯一的四边形
- graphdb - 启动时间很长 - GraphDB 8.7.2
- python - gspread:从 GoogleSheets 中检索过滤后的数据
- dart - 如何在 Flutter 运行时更改应用程序主题?
- python - 如何在 Django 中播放音频?
- firebase - Firestore 安全规则 - 验证传入数据长度是否大于 2,但字段不是必需的
- java - 处理时间的任何逻辑移动平均值
- python - 按位置将函数数组应用于元素数组