1. 程式人生 > >ConcurrentHashMap 原理(1)之內部類HashEntry 、Segment

ConcurrentHashMap 原理(1)之內部類HashEntry 、Segment

ConcurrentHashMap 的結構分析

ConcurrentHashMap 類中包含兩個靜態內部類 HashEntry 和 Segment。HashEntry 用來封裝對映表的鍵 / 值對;Segment 用來充當鎖的角色,每個 Segment 物件守護整個雜湊對映表的若干個桶。每個桶是由若干個 HashEntry物件連結起來的連結串列。一個 ConcurrentHashMap 例項中包含由若干個 Segment 物件組成的陣列。

HashEntry 類

HashEntry 用來封裝雜湊對映表中的鍵值對。在 HashEntry 類中,key,hash和 next 域都被宣告為 final 型,value 域被宣告為 volatile 型。


在 ConcurrentHashMap 中,在雜湊時如果產生“碰撞”,將採用“分離連結法”來處理“碰撞”:把“碰撞”的 HashEntry 物件連結成一個連結串列。由於 HashEntry 的 next 域為 final 型,所以新節點只能在連結串列的表頭處插入。 下圖是在一個空桶中依次插入 A,B,C 三個 HashEntry 物件後的結構圖:

圖 1. 插入三個節點後桶的結構示意圖:


注意:由於只能在表頭插入,所以連結串列中節點的順序和插入的順序相反。

Segment 類

Segment 類繼承於 ReentrantLock 類,從而使得 Segment 物件能充當鎖的角色。每個 Segment 物件用來守護其(成員物件 table 中)包含的若干個桶。

table 是一個由 HashEntry 物件組成的陣列。table 陣列的每一個數組成員就是雜湊對映表的一個桶。

count 變數是一個計數器,它表示每個 Segment 物件管理的 table 陣列(若干個 HashEntry 組成的連結串列)包含的 HashEntry 物件的個數。每一個 Segment 物件都有一個 count 物件來表示本 Segment 中包含的 HashEntry 物件的總數。注意,之所以在每個 Segment 物件中包含一個計數器,而不是在 ConcurrentHashMap 中使用全域性的計數器,是為了避免出現“熱點域”而影響 ConcurrentHashMap 的併發性。

清單 2.Segment 類的定義


下圖是依次插入 ABC 三個HashEntry 節點後,Segment 的結構示意圖。

圖 2. 插入三個節點後 Segment 的結構示意圖: