ConcurrentHashMap 實現原理
ConcurrentHashMap 的基本策略是將 table 細分為多個 Segment 保存在數組 segments 中,每個 Segment 本身又是一個可并發的哈希表,同時每個 Segment 都是一把 ReentrantLock 鎖,只有在同一個 Segment 內才存在競態關系,不同的 Segment 之間沒有鎖競爭,這就是分段鎖機制。Segment 內部擁有一個 HashEntry 數組,數組中的每個元素又是一個鏈表。下面看看 ConcurrentHashMap 整體結構圖:
為了減少占用空間,除了第一個 Segment 之外,剩余的 Segment 采用的是延遲初始化的機制,僅在第一次需要時才會創建(通過 ensureSegment 實現)。為了保證延遲初始化存在的可見性,訪問 segments 數組及 table 數組中的元素均通過 volatile 訪問,主要借助于 Unsafe 中原子操作 getObjectVolatile 來實現,此外,segments 中 segment 的寫入,以及 table 中元素和 next 域的寫入均使用 UNSAFE.putOrderedObject 來完成。這些操作提供了 AtomicReferenceArrays 的功能。
回答所涉及的環境:聯想天逸510S、Windows 10。
ConcurrentHashMap 實現原理
ConcurrentHashMap 的基本策略是將 table 細分為多個 Segment 保存在數組 segments 中,每個 Segment 本身又是一個可并發的哈希表,同時每個 Segment 都是一把 ReentrantLock 鎖,只有在同一個 Segment 內才存在競態關系,不同的 Segment 之間沒有鎖競爭,這就是分段鎖機制。Segment 內部擁有一個 HashEntry 數組,數組中的每個元素又是一個鏈表。下面看看 ConcurrentHashMap 整體結構圖:
為了減少占用空間,除了第一個 Segment 之外,剩余的 Segment 采用的是延遲初始化的機制,僅在第一次需要時才會創建(通過 ensureSegment 實現)。為了保證延遲初始化存在的可見性,訪問 segments 數組及 table 數組中的元素均通過 volatile 訪問,主要借助于 Unsafe 中原子操作 getObjectVolatile 來實現,此外,segments 中 segment 的寫入,以及 table 中元素和 next 域的寫入均使用 UNSAFE.putOrderedObject 來完成。這些操作提供了 AtomicReferenceArrays 的功能。
回答所涉及的環境:聯想天逸510S、Windows 10。