Java fair semaphore(Java公平信号量)
问题描述
我正在尝试理解这个旧考试任务的答案,在这个考试任务中,学生应该使用Java重入锁来实现公平的二进制信号量。我不明白这些计数器的意义:
int next = 0;
int nextToGo = 0;
int myNumber;
它在对任务的描述中说:"您可以假设程序中最多有20个线程使用信号量。此外,在程序的一次运行中最多执行1000万个信号量操作。" 在任务的解决方案中,它说:"每个试图获取信号量的线程都必须在队列中注册自己,并且只有在之前的线程离开它之后才能离开队列。每个线程使用32位计数器来记住它在队列中的位置。计数器不会回绕,因为最多会对信号量执行1000万次操作,但即使计数器可能回绕,代码也可以运行。"
在我看来,老师似乎在解决方案中忽略了1000万个线程的限制,但我的主要问题是,当线程被放入lock()和aWait()语句中的队列中,并且有一个正在检查的自由变量时,为什么需要计数器。而ReentrantLock(True)难道不考虑公平性吗?
解决方案:
public class FairSemaphore {
ReentrantLock l = new ReentrantLock(true);
Condition c = l.newCondition();
int next = 0;
int nextToGo = 0;
boolean free = true;
public void aqcuire() throws InterruptedException {
l.lock();
int myNumber = next++;
while(!(free && myNumber == nextToGo)) {
c.await();
}
free = false;
nextToGo++;
l.unlock();
}
public void release() {
l.lock();
free = true;
c.signalAll();
l.unlock();
}
}
推荐答案
虽然您可能会认为在可重入锁上阻塞的线程 排队,不能保证队列的行为像FIFO一样公平 排队。文档明确告诉您:
...此锁不保证任何特定的访问权限 秩序。 ..。但是请注意,锁的公平性并不能保证线程调度的公平性。...
阅读全文docs,即使您创建了公平的ReentrantLock,也不能保证它是公平的。
但是,显示的代码确实运行正常,因为计数器使线程以FIFO顺序获取锁。
代码是票证锁,因此也请签出https://en.wikipedia.org/wiki/Ticket_lock
这篇关于Java公平信号量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Java公平信号量
基础教程推荐
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01