1. 程式人生 > >3、Concurrenthashmap實現原理(JDK版本1.7)

3、Concurrenthashmap實現原理(JDK版本1.7)

同時 table 重新 最大 current cache jdk版本 con cto

(1)結構圖:

技術分享圖片

l ConcurrentHashMap中的數據結構

ConcurrentHashMap是由Segment數組結構和HashEntry數組結構組成。Segment實際繼承自可重入鎖(ReentrantLock),在ConcurrentHashMap裏扮演鎖的角色;HashEntry則用於存儲鍵值對數據。一個ConcurrentHashMap裏包含一個Segment數組,每個Segment裏包含一個HashEntry數組,我們稱之為table,每個HashEntry是一個鏈表結構的元素。

技術分享圖片

l ConcurrentHashMap實現原理或者ConcurrentHashMap如何在保證高並發下線程安全的同時實現了性能提升?

ConcurrentHashMap允許多個修改操作並發進行,其關鍵在於使用了鎖分離技術。它使用了多個鎖來控制對hash表的不同部分進行的修改。內部使用段(Segment)來表示這些不同的部分,每個段其實就是一個小的hash table,只要多個修改操作發生在不同的段上,它們就可以並發進行。

l ConcurrentHashMap初始化

初始化有三個參數

initialCapacity:初始容量大小 ,默認16。

loadFactor, 擴容因子,默認0.75,當一個Segment存儲的元素數量大於initialCapacity* loadFactor時,該Segment會進行一次擴容。

concurrencyLevel 並發度,默認16。並發度可以理解為程序運行時能夠同時更新ConccurentHashMap且不產生鎖競爭的最大線程數,實際上就是ConcurrentHashMap中的分段鎖個數,即Segment[]的數組長度。如果並發度設置的過小,會帶來嚴重的鎖競爭問題;如果並發度設置的過大,原本位於同一個Segment內的訪問會擴散到不同的Segment中,CPU cache命中率會下降,從而引起程序性能下降。

l put(K key, V value)

1、首先定位segment,當這個segment在map初始化後,還為null,由ensureSegment方法負責填充這個segment。

對Segment 加鎖

技術分享圖片

3、定位所在的table元素,並掃描table下的鏈表,找到時:

技術分享圖片

沒有找到時:

技術分享圖片

l 擴容操作

Segment 不擴容,擴容下面的table數組,每次都是將數組翻倍

技術分享圖片

好處是:可以快速定位和減少重排次數

l size()方法

size的時候進行兩次不加鎖的統計,兩次一致直接返回結果,不一致,重新加鎖再次統計

3、Concurrenthashmap實現原理(JDK版本1.7)