The*_*gle 3 java multithreading semaphore
我试图理解这个古老的考试任务的答案,应该让学生使用javas reentrantlock实现一个公平的二进制信号量。我不理解这些计数器的意义:
int next = 0;
int nextToGo = 0;
int myNumber;
Run Code Online (Sandbox Code Playgroud)
它在任务描述中说:“您可以假设使用信号量的程序中最多有20个线程。而且,在程序的一次运行中最多可以进行1000万次信号量的操作。” 在任务的解决方案中说:“每个尝试获取信号量的线程都必须将自己注册到队列中,并且仅在线程离开队列之后才离开队列。每个线程都使用32位内存来记住其在队列中的位置位计数器。计数器将不会回绕,因为最多可以对信号量执行一千万次操作,但是即使计数器可以回绕,代码也可以工作。”
在我看来,老师在解决方案中没有保留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();
}
}
Run Code Online (Sandbox Code Playgroud)
尽管您可能认为ReentrantLock上阻塞的线程已排队,但不能保证该队列的行为与FIFO队列相当。该文档明确告诉您:
...此锁不保证任何特定的访问顺序。...但是请注意,锁的公平性不能保证线程调度的公平性。...
阅读整个文档,即使您创建公平的ReentrantLock,也不能保证它是公平的。
但是,由于计数器使线程按FIFO顺序获取锁,因此显示的代码确实运行正常。
该代码是票证锁,因此也请查看https://en.wikipedia.org/wiki/Ticket_lock
| 归档时间: |
|
| 查看次数: |
437 次 |
| 最近记录: |