對於公平鎖,在鎖定隊列結束後,需要鎖定的鎖必須排列在鎖隊列的末尾。
下面的短程序演示了這種行爲。
- T1第一,然後調用等待獲取關於與該鎖相關的病症的鎖定。
- T2然後獲取該鎖,並等待,直到T3試圖獲取鎖,以及,然後調用上的狀態的信號。
- T3等待一些時間acuiring鎖定其是由T2保持之前。
當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
它應該是「不確定」(即它實際上取決於你的操作系統線程調度器),除非你有一個公平的鎖。操作系統可能不知道一個線程是否已經在等待,現在正在重新獲取,因此這些組之間應該沒有區別。另一方面,公平的鎖更喜歡最長的等待時間,不管他們等待的原因。 – zapl