JUC源碼分析(一):ConcurrentHashMap集合分析

ConcurrentHashMap類繼承至AbstractMap 實現接口ConcurrentMap,Serializable算法

這個類有如下主要的幾個靜態變量數組

DEFAULT_INITIAL_CAPACITY=16 初始化數組長度安全

DEFAULT_LOAD_FACTOR=0.75 默認裝載因子併發

DEFAULT_CONCURRENCY_LEVEL=16 默認併發級別ssh

MAXIMUM_CAPACITY=1<<30 最大數組長 1<<30高併發

MIN_SEGMENT_TABLE_CAPACITY=2 最小桶長度 線程

MAX_SEGMENTS=1<<16 最大桶數量指針

接下來是ConcurrentHashMap的構造器對象

1.能夠注意到其中的運算 sshift是併發級別的角標 注意 這裏的concurrencyLevel是2的倍數繼承

ssize能夠近似看做是concurrencyLevel

2。建立了一個桶對象 s0,和一個桶的數組長度爲ssize

這裏的HashEntry結構如圖

四個變量分別爲 key,(volatile修飾保證內存可見性)value,key的hash值(hash) 還有一個用volatile變量修飾的HashEntry元素指針 指向下一個元素

桶segment的類結構以下

桶的主要元素 是一個HashEntry的數組變量和一切其餘信息

因此 整個ConcurrentHashMap的結構是一個數組(segment)數組的每個元素仍是一個(HashEntry)數組

接下來看一下put方法

這裏的seqmentShift是經過併發等級獲得的值 併發等級爲N

則segmentShift=32-a,這裏得a=log2 N。2爲底N爲冪 的對數值

這裏的J至關於取 他的key的hash值得高a位

經過ensureSegment方法去獲取 hash值所在得桶segment對象 注意 在ConcurrentHashmap裏面獲取對象都是經過UNSAFE.getObjectVolatile去獲取得 而且經過CAS(compareAndSwap)算法 去比較賦值 這是保證在高併發下數據保持一致得一種算法

CAS算法 是 有三個值 一個原始值K,一個修改值B,一個預估值A

在修改得時候 先比較原始值 和預估值(在預估值上進行計算獲得修改值),當且這兩個值相等的時候,纔將修改值 寫入內存

能夠看到

1.加鎖

2.調用桶 segment得put方法,經過拿到得桶對象,獲取第一個HashEntry數組元素,依次往下遍歷,第一個IF判斷裏是HashEntry[] 裏有相同得Key值元素得時候 進行值替換操做 而且控制角標往數組下方移動

3.else裏面則是當角標移動到數組最後一位得時候進行元素得新建操做

4.解鎖

能夠看到,整個ConcurrentHashMap是一個數組加數組加鏈表得結構 

其中HashEntry 在內存上連續 在結構上經過index關聯 而後經過next指針關聯一串鏈表

在對每個桶(segment)操做得時候 對其中得HashEntry[](表結構)會進行加鎖(trylock)和解鎖(unlock)操做 這就是ConcurrentHashMap得分段鎖機制。將每個桶單獨作成一個HashMap結構 在高併發得時候 以表結構爲單位進行操做。而且經過CAS算法 確保了數據得一致性。因此 ConcurrentHashMap相較於Hashtable而言是效率更高得 相對於HashMap而言 是線程安全得

相關文章
相關標籤/搜索