1. 程式人生 > >關於Java鎖幾個解釋

關於Java鎖幾個解釋

分類

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

 

公平鎖/非公平鎖

公平鎖:各個執行緒按請求鎖的順序來獲取物件鎖。

非公平鎖:公平鎖的反面,缺點,優先順序反轉,高優先順序的可能得不到鎖,飢餓現象。

優點:高併發的吞吐量比公平鎖大。對應的類是Synchronized,ReentrantLock,區別reentrantlock可以實現公平鎖,synchronized不行。

 

可重入鎖

又名遞迴鎖,是指在同一個執行緒在外層方法獲取鎖的時候,在進入內層方法會自動獲取鎖。

案例

一個帶synchronized方法A,裡面含有一個synchronized方法B,當開始執行方法A時候,現場執行緒會去獲取鎖,程式碼執行到方法B的時候,該執行緒還會去獲取B方法的鎖。優點,防止死鎖,打個比方,就上面的案例,假設執行B的時候沒有去獲取鎖,一個線做的過程是AB,另一個執行緒執行的是BA,這個時候AB的A鎖定了,BA的B鎖定了,AB執行B過不去,BA執行A過不去,資源互鎖,死鎖就產生了。

synchronized void A() throws Exception{   

   B();
}

synchronized void B() throws Exception{
    
}

 

獨享鎖/共享鎖

這個東西就是一個概念,獨享鎖就是該鎖只能給一個執行緒用,共享鎖就是該鎖可以給多個執行緒用。

獨享鎖有Synchronized,ReentrantLock。readwritelock的寫鎖。

共享鎖有readwritelock的讀鎖。

互斥鎖/讀寫鎖

也是一種概念。

互斥鎖在Java中的具體實現就是ReentrantLock
讀寫鎖在Java中的具體實現就是ReadWriteLock

樂觀鎖/悲觀鎖

這也是一種概念。

 樂觀鎖認為,多個執行緒對同一個資料就進行操作是沒有影響的,在更新資料的時候,會採用嘗試更新,不斷更新的方式更新資料。(換句話說它認為所有測操作都是讀操作)。

悲觀鎖認為,多個執行緒對同一個資料操作都是更新操作,不加鎖的併發操作一定會出問題,需要對那段程式碼加鎖。(換句話說它認為所有測操作都是寫操作)。

分段鎖

一種概念。

對於ConcurrentHashMap而言,其併發的實現就是通過分段鎖的形式來實現高效的併發操作。

ConcurrentHashMap中的分段鎖稱為Segment,它即類似於HashMap的結構,即內部擁有一個Entry陣列,陣列中的每個元素又是一個連結串列;同時又是一個ReentrantLock(Segment繼承了ReentrantLock)。
當需要put元素的時候,並不是對整個hashmap進行加鎖,而是先通過hashcode來知道他要放在那一個分段(桶)中,然後對這個分段(桶)進行加鎖,所以當多執行緒put的時候,只要不是放在一個分段中,就實現了真正的並行的插入。但是,在統計size的時候,可就是獲取hashmap全域性資訊的時候,就需要獲取所有的分段鎖才能統計。
分段鎖的設計目的是細化鎖的粒度,當操作不需要更新整個陣列的時候,就僅僅針對陣列中的一項進行加鎖操作。

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

這三種鎖是指鎖的狀態,並且是針對Synchronized

在Java 5通過引入鎖升級的機制來實現高效Synchronized。這三種鎖的狀態是通過物件監視器在物件頭中的欄位來表明的。
偏向鎖: 指一段同步程式碼一直被一個執行緒所訪問,那麼該執行緒會自動獲取鎖。降低獲取鎖的代價。
輕量級鎖:指當鎖是偏向鎖的時候,被另一個執行緒所訪問,偏向鎖就會升級為輕量級鎖,其他執行緒會通過自旋的形式嘗試獲取鎖,不會阻塞,提高效能。
重量級鎖:指當鎖為輕量級鎖的時候,另一個執行緒雖然是自旋,但自旋不會一直持續下去,當自旋一定次數的時候,還沒有獲取到鎖,就會進入阻塞,該鎖膨脹為重量級鎖。重量級鎖會讓其他申請的執行緒進入阻塞,效能降低。

自旋鎖

在Java中,自旋鎖是指嘗試獲取鎖的執行緒不會立即阻塞,而是採用迴圈的方式去嘗試獲取鎖,這樣的好處是減少執行緒上下文切換的消耗,缺點是迴圈會消耗CPU。