2014-01-16 37 views
3

方法Condition.newCondition()的Javadoc狀態爲「從等待方法返回的線程的鎖重新獲取的順序與最初獲取鎖的線程的順序相同,這是在默認情況下沒有規定,但對於公平鎖定有利於那些線程一直在等待的時間最長。在Java中的信號線程和最初獲取鎖的線程之間顯式鎖定獲取順序

這是否意味着,與明確的鎖,從條件的線程覺醒的鎖定獲取競爭在一起線程最初獲取它,就像隱式鎖發生一樣?

換句話說,有兩組線程,一個是第一次嘗試獲取鎖的線程,另一個是在等待條件並被髮信號後嘗試重新獲取鎖的線程,後者在鎖定收購方面比前者更受青睞?

鎖公平值是否以任何方式影響這兩個組的鎖定獲取順序?

+1

它應該是「不確定」(即它實際上取決於你的操作系統線程調度器),除非你有一個公平的鎖。操作系統可能不知道一個線程是否已經在等待,現在正在重新獲取,因此這些組之間應該沒有區別。另一方面,公平的鎖更喜歡最長的等待時間,不管他們等待的原因。 – zapl

回答

2

換句話說,有兩組線程,一組試圖首次獲得鎖,另一組試圖在等待條件並被髮信號後重新獲取鎖,後者是否對鎖定收購有利?

沒有,除非Lock是「公平」,這是最有可能是相反的:典型的實現有利於剛獲取Lock,因爲它有較少的開銷讓該線程成功,而不是把該線程睡眠和喚醒線程另一個。

鎖定公平值是否以任何方式影響這兩個組的鎖定獲取順序?

不,鎖定收購使得在這一點上沒有區別。當在Condition上等待的線程發送信號時,可能有其他線程等待第一次採集時間更長。而一個「公平的」Lock將喜歡最長的等待線程。

0

對於公平鎖,在鎖定隊列結束後,需要鎖定的鎖必須排列在鎖隊列的末尾。

下面的短程序演示了這種行爲。

  • 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