2015-07-12 72 views
3

每個博客或解釋我看到鎖定API優於同步。鎖定同步的優點API

我想知道是否有任何鎖定同步的優點,或者我更喜歡同步而不是鎖定的任何情況。

回答

7

你的意思是synchronized語句和methods關鍵字嗎?隱式鎖定的主要優點是需要更少的代碼,並在離開其範圍時自動解鎖。對於簡單的鎖定/等待操作來說,這是完美的解決方案

所以下面的代碼

public void myMethod() { 
    synchronized(this) { 
     // concurrent stuff 
    } 
} 

完全等價於

final private Lock lock = new ReentrantLock(); 

public void myMethod() { 
    lock.lock(); 
    try { 
     // concurrent stuff 
    } 
    finally { 
     lock.unlock(); 
    } 
} 

synchronized public void myMethod() { 
    // concurrent stuff 
} 

您還可以使用同步的不同對象(他們沒有受到任何影響,僅作爲控制點):

final static private Object sync = new Object(); 

public void method1() { 
    synchronized(sync) { 
     // concurrent code involving static members 
    } 
} 

public void method2() { 
    synchronized(this) { 
     // concurrent code affecting this instance 
    } 
} 
6

除了@ Shepard的回答,使用​​不太容易出錯。考慮這些可能導致鎖不能被釋放的錯誤:

final private Lock lock = new ReentrantLock(); 

public void myMethod() { 
    lock.lock(); 
    // concurrent stuff 
} 

public void myMethod2() { 
    lock.lock(); 
    // concurrent stuff that might throw an unchecked exception 
    lock.unlock(); 
} 

public void myMethod3() { 
    lock.lock(); 
    try { 
     // concurrent stuff 
     lock.unlock(); 
    } catch (...) { 
     ... 
    } finally { 
     ... 
    } 
} 

第一個可能會出現在測試中,但後兩個可能不會。

你不能用​​來犯這些錯誤。


然而,儘管Lock這些考慮是有用的:

  • 鎖,可以實現不同的鎖定策略,如非重入鎖,多讀/單寫鎖。

  • 鎖定允許您在範圍/塊結構邊界上保持鎖定。 (這會讓你的代碼難以推理,但對於某些使用案例是必要的;例如,需要在多個事件處理程序中鎖定的基於事件的設計。)

  • Lock API允許您測試鎖定,無阻塞地獲取鎖定或超時,並定義對象。