concurrentHashMap實現原理

JDK6與JDK7中的實現:
理解concurrentHashMap首先最關鍵先理解一個概念:segment
segment是什麼呢?segment自己就至關於一個HashMap對象,同時又繼承了ReentrantLock;同HashMap同樣,segment包含一個HashEntry數組,數組的每個HashEntry既是一個鍵值對,也是一個鏈表的頭節點;HashEntry中的value和next都被volatile修飾,用於多線程保證可見性。
像這樣的segment對象,在concurrentHashMap中集合中有2的N次方個,共同保存在一個名爲segments的數組當中。
 
所以整個ConcurrentHashMap的結構以下:
concurrentHashMap是在一個總的哈希表下面,有若干個子哈希表。這樣的二級結構,數據庫的水平拆分有些類似。
這樣設計的優點在於:才用了鎖分段技術,每個segment就比如一個自治區,讀寫操做高度自治,segment之間互不影響。
不一樣segment的寫入能夠併發執行,同一個segment的讀寫能夠併發執行,同一個segment的併發寫會被阻塞。因而可知,concurrentHashMap當中每一個segment各自持有一把鎖。在保證線程安全的同時下降了鎖的粒度,讓併發操做效率更高。
ConcurrentHashMap的讀寫詳細過程:
Get方法:
1.爲輸入的key作hash運算,獲得hash值
2.經過hash值,定位到對應的segment對象
3.再次經過hash值,定位到segment當中數組的具體位置
Put方法:
1.爲輸入的key作Hash運算,獲得hash值
2.經過hash值,定位到對應的segment對象
3.獲取可重入鎖
4.再次經過hash值,定位到segment當中的數組的具體位置
5.插入活覆蓋hashEntity對象
6.釋放鎖
 
ConcurrentHashMap的size方法是一個嵌套循環,答題邏輯以下:
1.遍歷全部segment
2.把segment的元素數量累加起來
3.再一次把segment的元素數量累加起來
4.判斷這一次與上一次統計的是否一致,不一致,從新統計,嘗試次數+1;若是不是,說明沒有修改,統計結束
5.若是嘗試次數超過了閾值,則對每個segment加鎖,再從新統計
6.再次判斷全部segment的總修改次數是否大於上一次的總修改次數;因爲已經加鎖,次數必定和上次相等
7.釋放鎖,統計結束
 
ConcurrentHashMap在對Key求Hash值的時候,爲了實現Segment均勻分佈,進行了兩次Hash。
 
併發度的概念:
  能夠理解爲:可以同時跟新ConcurrentHashMap且不產生鎖競爭的最大線程數,實際上就是ConcurrentHashMap的分段鎖個數,即Segment[]數組的長度。

rehash的概念:
    相對於HashMap的resize,ConcurrentHashMap的rehash原理相似,可是作了必定的優化,避免讓全部的節點都進行復制操做:因爲擴容是基於2的冪指來操做,假設擴容前某HashEntry對應到Segment中數組的index爲i,數組的容量爲capacity,那麼擴容後該HashEntry對應到新數組中的index只可能爲i或者i+capacity,所以大多數HashEntry節點在擴容先後index能夠保持不變。基於此,rehash方法中會定位第一個後續全部節點在擴容後index都保持不變的節點,而後將這個節點以前的全部節點重排便可。

node

ConcurrentHashMap是弱一致性,get到的數據多是過期的。ConcurrentHashMap不容許key或者value爲null。算法

JDK8中的實現:數據庫

  摒棄了Segment分段鎖的概念,啓用了CAS算法,底層依然由 「數組」 + 鏈表 + 紅黑樹的方式;爲了併發,添加了例如:TreeBin、Traverser等內部對象類。數組

  sizeCtl屬性:負值表明正在進行初始化或者擴容,-1表明正在初始化 ,-N表明有N-1個線程正在擴容;正數或者0表明hash表尚未被初始化,這個值標識初始化或者下一次擴容的大小,始終未ConcurrentHashMap容量的0.75倍,與loadfactor對應。安全

  不採用segment而採用node,鎖住node來實現減少鎖粒度。
  設計了MOVED狀態 當resize的中過程當中 線程2還在put數據,線程2會幫助resize。
  使用3個CAS操做來確保node的一些操做的原子性,這種方式代替了鎖。
  sizeCtl的不一樣值來表明不一樣含義,起到了控制的做用。

多線程

相關文章
相關標籤/搜索