提问人:mattsmith5 提问时间:11/13/2023 最后编辑:mattsmith5 更新时间:11/13/2023 访问量:41
Java:允许人们通过门的程序
Java: Program to allow people through a Gate
问:
我正在编写一个程序来执行 5 个门计数,然后允许人们进入建筑物(通过执行 System.out.println)。
我有以下解决方案,使用同步。但是,有人提到此解决方案不允许排队人员的顺序锁定公平性。我怎样才能重写它以允许它?下面的信号量是否正确?
使用 Synchronized:
public class LineCount {
int totalInLine = 0;
public synchronized void addToLine() {
totalInLine = totalInLine + 1;
if (totalInLine == 5) {
System.out.println("People may enter");
totalInLine = 0;
}
}
使用信号量:
public class LineCount {
Semaphore semaphore = new Semaphore(5, true);
public void addToLine() throws InterruptedException {
semaphore.acquire();
if (semaphore.availablePermits() == 0) {
System.out.println("People may enter");
semaphore.release(5);
semaphore = new Semaphore(5, true);
}
}
}
答:
版本差不多,但与版本不完全相同。但是,该版本不是线程安全的。我建议进行两项更改:Semaphore
synchronized
Semaphore
public class LineCount {
final Semaphore semaphore = new Semaphore(5, true); // added `final` keyword
public void addToLine() throws InterruptedException {
semaphore.acquire();
if (semaphore.availablePermits() == 0) {
System.out.println("People may enter");
semaphore.release(5);
// semaphore = new Semaphore(5, true); // **Don't Do This**
}
}
}
原因是,如果某个线程 A 执行了该语句,则线程 B 可能会溜进来,并在线程 A 的赋值生效之前递减旧的信号量。这将允许在下次打印消息之前进行五次以上的调用。semaphore.release(5)
semaphore = new Semaphore(...)
无需创建新的信号量,因为每次调用将允许另外五个调用来获取许可证。release(5)
原因主要是为了确保每个阅读代码的人都会立即理解总是引用同一个对象。final
semaphore
更新:
然而,有人提到,该解决方案不允许排队的人实现顺序锁定公平性。
synchronized
我什至猜不出这意味着什么。你应该问“某人”清楚。
您的版本每五次呼叫都会打印一条消息。它不做任何其他事情。它不会使任何呼叫者等待的时间超过其他呼叫者打印消息所需的时间。其中的“不公平”在哪里?synchronized
addToLine
您问题的标题是“允许人们通过大门的程序”。但这里没有任何东西可以真正模拟大门。里面没有任何东西可以让任何“人”等待“门”“打开”。从字面上看,它只是一种线程安全的方法,每五次调用都会打印一条特定消息。
评论
addToLine
评论