1. 程式人生 > >java鎖有哪些類(轉)

java鎖有哪些類(轉)

一次 http san fan 宋體 ans 名詞 set 預測

轉載來源:http://www.cnblogs.com/lxmyhappy/p/7380073.html

1Java都有哪些鎖?

  • 公平鎖/非公平鎖
  • 可重入鎖
  • 獨享鎖/共享鎖
  • 互斥鎖/讀寫鎖
  • 樂觀鎖/悲觀鎖
  • 分段鎖
  • 偏向鎖/輕量級鎖/重量級鎖
  • 自旋鎖

Java實現鎖有兩種語法,一種是synchronized語句,另外一種是reentrantlock關鍵字。上面是很多鎖的名詞,這些分類並不是全是指鎖的狀態,有的指鎖的特性,有的指鎖的設計,下面總結的內容是對每個鎖的名詞進行一定的解釋

公平鎖/非公平鎖

公平鎖指多個線程按照申請鎖的順序獲得鎖。

非公平鎖指多個線程獲得鎖的順序不按照申請順序。

Java reentranthlock通過構造函數來指定鎖是公平還是非公平,默認是非公平鎖,對於

synchronized而言,也是一種非公平鎖。

非公平鎖優點在於吞吐量比公平鎖大。

可重入鎖

可重入鎖又叫遞歸鎖,是指同一個線程在外層方法獲取鎖的時候,在進入內層方法會自動獲取鎖。舉例如下:

synchronized void setA() throws Exception{
    Thread.sleep(1000);
    setB();
}
synchronized void setB() throws Exception{
    Thread.sleep(1000);
}

Java reentrantlock是一個可重入鎖。上面的代碼就是一個可重入鎖的一個特點,如果不是可重入鎖的話,

setB可能不會被當前線程執行,可能造成死鎖

Synchronized也是一個可重入鎖。

可重入鎖的優點是可以一定程度避免死鎖。

獨享鎖/共享鎖

顧名思義,獨享鎖是指該鎖一次只能被一個線程所持有,共享鎖可以被多個線程所持有。

Java reentrantlock是一個獨享鎖,但是對於lock的另一個實現readwritelock,其讀鎖是一個共享鎖,寫鎖是一個獨享鎖。

對於synchronized是一個獨享鎖。

互斥鎖/讀寫鎖

上邊說的獨享鎖和共享鎖是一種廣義的說法,互斥鎖和讀寫鎖就是具體實現。

互斥鎖在Java中具體實現就是reentrantlock

讀寫鎖在Java中的具體實現就是readwritelock

樂觀鎖/悲觀鎖

樂觀鎖和悲觀鎖不是指具體的鎖類型,而是對於看待並發編程中加鎖問題的角度。

悲觀鎖認為,對於一個數據的並發操作,一定會改變數據,即使實際上數據沒被改變,但是也悲觀的認為被改變的可能性比較大,一定要加鎖,不加鎖早晚要出問題。

樂觀鎖認為,對於一個數據的並發操作,是不會改變數據的,不加鎖也不會出問題。

樂觀鎖指java中的無所編程,適合讀操作非常多的場景。

悲觀鎖就是指java中,適合並發下寫非常多的場景。

自旋鎖

java中,自旋鎖是指常識獲取鎖的線程不會立即阻塞,而是采用循環的方式去嘗試獲取鎖,當循環條件被其他線程改變時,才能進入臨界區。這樣的好處是減少線程上下文切換的消耗,缺點是會消耗CPU

public class SpinLock {

  private AtomicReference<Thread> sign =new AtomicReference<>();

  public void lock(){
    Thread current = Thread.currentThread();
    while(!sign .compareAndSet(null, current)){
    }
  }
  public void unlock (){
    Thread current = Thread.currentThread();
    sign .compareAndSet(current, null);
  }
}

使用了CAS原子操作,lock函數將owner設置為當前線程,並且預測原來的值為空。unlock函數將owner設置為null,並且預測值為當前線程。

當有第二個線程調用lock操作時由於owner值不為空,導致循環一直被執行,直至第一個線程調用unlock函數將owner設置為null,第二個線程才能進入臨界區。

由於自旋鎖只是將當前線程不停地執行循環體,不進行線程狀態的改變,所以響應速度更快。但當線程數不停增加時,性能下降明顯,因為每個線程都需要執行,占用CPU時間。如果線程競爭不激烈,並且保持鎖的時間段。適合使用自旋鎖。

註:該例子為非公平鎖,獲得鎖的先後順序,不會按照進入lock的先後順序進行。

偏向鎖/輕量級鎖/重量級鎖

這三種鎖,就是指鎖的狀態,針對synchronized

偏向鎖是指一段代碼一直被一個線程所訪問,那麽理論上,這個線程會自動獲取這個鎖,並一直擁有這個鎖,這樣就降低了獲取鎖的代價。

輕量級鎖是指當偏向鎖的狀態下,被另一個線程訪問,偏向鎖就會升級為輕量級鎖,其他線程會通過自旋形式嘗試獲取鎖,不會阻塞,提高效率。

重量級鎖是指在輕量級鎖的狀態下,另一個線程雖然自旋,但自選不會一直持續下去,當自旋一定次數的時候還沒有獲取到鎖的話,就會進入阻塞,該鎖就會膨脹為重量級鎖,重量級鎖會讓其他申請的線程陷入阻塞,降低性能。

java鎖有哪些類(轉)