问题描述
问题:我有一组 Thread
,其中一些在获取 reentrantlock
时必须优先于其他。
解决方案:我可以想象有一个 公平 reentrantlock
与 2 {{ 1}} 个队列:Condition
和 lowPriority
。重点是 highPriority
在 highPriority
之前发出信号。考虑到 lowPriority
的公平性,在 reentrantlock
中被阻止的 Thread
必须总是先于在 highPriority
中被阻止的 Thread
。
实施:
lowPriority
问题: 让我对解决方案感到困惑的问题是,我无法从 JMM 的角度正式证明一旦有 public class Main {
public static final Lock lock = new reentrantlock(true);
public static final Condition lowPriority = lock.newCondition();
public static final Condition highPriority = lock.newCondition();
public static boolean cond;
public static void lowPriority() throws InterruptedException {
try {
lock.lock();
while(!cond) {
lowPriority.await();
}
cond = false;
System.out.println("low");
} finally {
lock.unlock();
}
}
public static void highPriority() throws InterruptedException {
try {
lock.lock();
while(!cond) {
highPriority.await();
}
cond = false;
System.out.println("high");
} finally {
lock.unlock();
}
}
public static void setCond(){
try{
lock.lock();
cond = true;
highPriority.signalAll();
lowPriority.signalAll();
} finally {
lock.unlock();
}
}
}
被阻止在 Thread
,他们总是在 highPriority
赢得 Thread
。
当然,我进行了一些实验,高优先级线程总是获胜,但形式上正确吗?
解决方法
据我所知,对于代码
labels[language] ?? "Unknown"
不能保证等待 highPriority.signalAll();
lowPriority.signalAll();
的线程会在等待 highPriority
的任何线程之前唤醒。
即使 lowPriority
线程可以以随机顺序唤醒1:
但是请注意,锁的公平性并不能保证线程调度的公平性。因此,使用公平锁的许多线程中的一个可能会连续多次获得它,而其他活动线程没有进行并且当前没有持有锁。
此外,fairness==true
将继续唤醒所有低优先级线程,即使该进程中间出现新的高优先级线程。
所以我会在 lowPriority.signalAll()
附加逻辑的开头插入,它检查是否有任何等待的高优先级线程,如果有,让它们先运行。
类似的东西:
lowPriority