方法Condition.newCondition()
的Javadoc声明“从等待方法返回的线程的锁重新获取的顺序与最初获取锁的线程的顺序相同,这是默认情况下未指定的,但是公平锁有利于那些等待时间最长的线程。“
这是否意味着,使用显式锁定,从条件中唤醒的线程与最初获取它的线程一起竞争锁定获取,就像使用隐式锁定一样?
换句话说,拥有两组线程,一组试图第一次获得锁定,另一组试图在等待条件并发出信号后重新获取锁定,后者是后者锁定收购比前者更受青睐?
锁定公平性值是否会以任何方式影响这两个组的锁定获取顺序?
答案 0 :(得分:2)
换句话说,拥有两组线程,一组试图第一次获得锁定,另一组试图在等待条件并发出信号后重新获取锁定,后者是后者锁定收购比前者更受青睐?
不,除非Lock
是“公平的”,否则很可能相反:典型的实现有利于线程只是获取Lock
,因为它让开头成功而不是放入线程睡觉,唤醒另一个。
锁定公平性值是否会以任何方式影响这两个组的锁定获取顺序?
不,锁定获取在那一点没有区别。当发出等待Condition
的线程时,可能有其他线程等待第一次获取更长时间。并且“公平”Lock
将更喜欢最长的等待线程。
答案 1 :(得分:0)
对于公平锁定,在单击后需要锁定的therad必须在锁定队列的末尾排队。
以下简短程序演示了此行为。
当T2调用信号时,T1尝试重新获取锁定。当T2释放锁定时,T1和T3都在竞争锁定,但T3首先获得锁定。
public class Test {
public static void main(String[] args) throws Exception {
final Lock r = new ReentrantLock(true);
final Condition c = r.newCondition();
Thread t1 = new Thread( () -> {
System.out.println("T1 try lock");
r.lock();
System.out.println("T1 got lock");
System.out.println("T1 invokes await and releases lock");
try { c.await(); } catch (InterruptedException e) { }
System.out.println("T1 reqcquired lock");
r.unlock();
} );
Thread t2 = new Thread( () -> {
sleep(50);
System.out.println("T2 try lock");
r.lock();
System.out.println("T2 got lock");
sleep(100);
c.signal();
System.out.println("T2 signaled");
sleep(100);
r.unlock();
} );
Thread t3 = new Thread( () -> {
sleep(100);
System.out.println("T3 try lock");
r.lock();
System.out.println("T3 got lock");
r.unlock();
} );
t1.start();
t2.start();
t3.start();
}
static void sleep(long millis) {
try { Thread.sleep(millis); } catch (InterruptedException e) { }
}
}
输出
T1 try lock
T1 got lock
T1 invokes await and releases lock
T2 try lock
T2 got lock
T3 try lock
T2 signaled
T3 got lock
T1 got signal and reqcquired lock