Condition.newCondition()
方法的Javadoc声明:“从等待方法返回的线程的锁重新获取顺序与最初获取锁的线程相同,在默认情况下没有指定,但是对于公平的锁,对那些等待时间最长的线程来说是有利的。”
这是否意味着,通过显式锁,从条件中唤醒的线程与最初获取锁的线程竞争,就像在隐式锁中发生的那样?
换句话说,有两组线程,一组是第一次尝试获取锁,另一组是在等待并被发送信号后试图重新获取锁,后者在锁定获取时是否比前者更受青睐?
锁公平性值是否以任何方式影响这两个组的锁获取顺序?
发布于 2014-01-16 20:08:07
换句话说,有两组线程,一组是第一次尝试获取锁,另一组是在等待并被发送信号后试图重新获取锁,后者在锁定获取时是否比前者更受青睐?
不,除非Lock
是“公平的”,否则很可能相反:典型的实现倾向于线程只是获取Lock
,因为它拥有较少的开销让线程成功,而不是让该线程休眠并唤醒另一个线程。
锁公平性值是否以任何方式影响这两个组的锁获取顺序?
不,锁的收购在那一点上没什么区别。当一个等待在Condition
上的线程发出信号时,可能会有其他线程第一次等待时间更长。“公平”的Lock
会更喜欢等待时间最长的线程。
发布于 2015-03-08 17:36:13
为了实现公平的锁,在发出信号后要求锁定的服务器必须在锁队列的末尾排队。
下面的简短程序演示了此行为。
当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
https://stackoverflow.com/questions/21168811
复制相似问题