1. 程式人生 > 實用技巧 >ConcurrentHashMap底層結構分析

ConcurrentHashMap底層結構分析

jdk1.7的ConcurrentHashMap

  • 底層資料結構: 分段的陣列+連結串列。ConcurrentHashMap是由Segment資料結構和HashEntry資料結構組成。Segment實現了ReentrantLock,所以Segment是一種可重入鎖,扮演鎖的角色。HashEntry用於儲存鍵值對資料。一個ConcurrentHashMap包含一個Segment陣列。Segment陣列中的每個元素包含一個HashEntry陣列,HashEntry陣列中的每個元素是一個連結串列結構的元素。Segment陣列的每個元素各守護著一個HashEntry陣列中的素有元素。當對HashEntry陣列的資料進行修改時,必須首先獲得對應的Segment陣列元素的鎖
    在這裡插入圖片描述
  • 實現執行緒安全的方式: 首先將資料分為一段一段的儲存,然後給每一段資料配一把鎖,當一個執行緒佔用鎖訪問其中一個段資料時,其他段的資料也能被其他執行緒訪問,提高併發訪問率。

jdk1.8的ConcurrentHashMap

  • 底層資料結構: ConcurrentHashMap取消了Segment分段鎖,採用CAS(Compare-and-Swap,比較並替換)和synchronized來保證併發安全。資料結構跟HashMap1.8的結構類似, 是陣列+連結串列/紅黑樹。(jdk1.6以後對synchronized鎖做了很多優化,比如偏向鎖、輕量級鎖、自旋鎖、鎖消除、鎖粗化等)
  • 實現執行緒安全的方式:

    在jdk1.7的時候,ConcurrentHashMap採用分段鎖,對整個桶陣列進行了分割分段(Segment),每一把鎖只鎖容器其中一部分,多執行緒訪問容器裡不同資料段的資料,就不會產生鎖競爭,提高併發訪問率。
    到了jdk1.8的時候 ,synchronized只鎖定當前連結串列或者紅黑樹的首節點,這樣只要hash不衝突,就不會產生併發,效率又提升N倍。

jdk1.8的ConcurrentHashMap(TreeBin:紅黑樹節點;Node:連結串列節點)
在這裡插入圖片描述