我已经通过RentrantLock
接受了公平和非公平纪律的测试。我写了一个模拟哲学家吃饭的小程序。
每个哲学家都有左右叉子,分别是ReentrantLock
s。我模拟了1000次思考和进食行为:
for (int i = 0; i < ACT_TIMES; i++) {
act();
}
act
在哪里
private void act() {
think();
eat();
}
想想
没什么意思,只是睡了一段时间而已。下面是eat的方法
private void eat() {
try {
if (left.tryLock(0, TimeUnit.MILLISECONDS)) {
if (right.tryLock(0, TimeUnit.MILLISECONDS)) {
log("eating");
eatCount++;
try {
Thread.sleep(EAT_TIME);
} catch (InterruptedException e) {
} finally {
left.unlock();
right.unlock();
}
} else {
left.unlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
主要方法:
Lock[] forks = new Lock[5];
for (int i = 0; i < forks.length; i++) {
forks[i] = new ReentrantLock();
}
Philosopher p1 = new Philosopher(0, forks[1], forks[0]);
Philosopher p2 = new Philosopher(1, forks[2], forks[1]);
Philosopher p3 = new Philosopher(2, forks[3], forks[2]);
Philosopher p4 = new Philosopher(3, forks[4], forks[3]);
Philosopher p5 = new Philosopher(4, forks[0], forks[4]);
ExecutorService exec = Executors.newFixedThreadPool(5);
exec.submit(p1);
exec.submit(p2);
exec.submit(p3);
exec.submit(p4);
exec.submit(p5);
完成所有5个线程后,我为每个哲学家打印eatCount。这些值对于公平(
new ReentantLock(true)
)和不公平(new ReentantLock()
)纪律没有太大差异。
(第一个数字是一个哲学家的数字)
公平锁定:
0 344
1 348
2 366
3 359
4 363
Total number of eating 1780
不公平锁定:
0 338
1 338
2 339
3 341
4 352
Total number of eating 1708
我曾预料到一些哲学家会挨饿,我的意思是有些哲学家必须比其他人吃得多,但饥饿并没有发生。为什么?
@Maks,你试过为EAT_TIME设置随机值吗?
这可能会给逻辑带来一些不公平。
删除所有睡眠()
,你可能会看到一些不公平。
释放锁的线程有更好的机会重新获得锁,因为它很忙,而其他线程可能被阻塞。繁忙等待不会显示这一点,因为每个线程都有均等的机会获取锁。释放锁的那个可能有点不利。
final ReentrantLock lock = new ReentrantLock();
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 5; j++) {
lock.lock();
System.out.println("locked by " + finalI);
lock.unlock();
}
}
}).start();
}
印刷品
locked by 0
locked by 0
locked by 0
locked by 0
locked by 0
locked by 1
locked by 1
locked by 1
locked by 1
locked by 1
locked by 2
locked by 2
locked by 2
locked by 2
locked by 2
locked by 3
locked by 3
locked by 3
locked by 3
locked by 3
locked by 4
locked by 4
locked by 4
locked by 4
locked by 4
但是如果我让锁变得公平
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
本文向大家介绍ReentrantLock源码详解--公平锁、非公平锁,包括了ReentrantLock源码详解--公平锁、非公平锁的使用技巧和注意事项,需要的朋友参考一下 问题 (1)重入锁是什么? (2)ReentrantLock如何实现重入锁? (3)ReentrantLock为什么默认是非公平模式? (4)ReentrantLock除了可重入还有哪些特性? 简介 Reentrant = Re
当锁被释放后,任何一个线程都有机会竞争得到锁,这样做的目的是提高效率,但缺点是可能产生线程饥饿现象。
本文向大家介绍请讲一下非公平锁和公平锁在reetrantlock里的实现过程是怎样的。相关面试题,主要包含被问及请讲一下非公平锁和公平锁在reetrantlock里的实现过程是怎样的。时的应答技巧和注意事项,需要的朋友参考一下 考察点:锁 如果一个锁是公平的,那么锁的获取顺序就应该符合请求的绝对时间顺序,FIFO。对于非公平锁,只要CAS设置同步状态成功,则表示当前线程获取了锁,而公平锁还需要判断
我试图理解这个旧考试任务的答案,在这个任务中,学生应该使用JavasReentrantLock实现一个公平的二进制信号量。我不明白这些计数器的意义: 它在任务的描述中说,“你可以假设程序中使用信号量最多有20个线程。此外,最多1000万信号量操作将在程序的一次运行中执行。"在任务的解决方案中,它说:“每个试图获取信号量的线程必须在队列中注册自己,并且只有在之前的线程离开队列后才离开队列。每个线程使
如何使用约束流api计算员工的公平性。 https://www.optaplanner.org/blog/2017/02/03/FormulaForMeasuringUnfairness.html 我在网球求解器示例中看到了上述流口水的实现。 https://github.com/kiegroup/optaplanner/blob/581d10fb8140f37b7491d06b2bab8d5ac
在B. Goetz的Java实践中的并发,第13.5节说: 在Java5.0中,读锁的行为更像是一个信号量而不是锁,只维护活动读卡器的数量,而不是它们的身份。Java 6中的行为已更改,以跟踪哪些线程已被授予读锁6。 6这种变化的一个原因是,在java 5.0下,锁实现不能区分第一次请求读锁的线程和重入锁请求,这将使公平读写锁容易死锁。 我的问题是公平有什么问题?为什么不公平的读写锁会被死锁屏蔽?