Hashtable 使用單一鎖鎖定整張表,並發性能差。ConcurrentHashMap 採用鎖分離技術,內部分為多個段,每段獨立加鎖,允許多線程並發修改不同段。

ConcurrentHashMap 持有 final Segment[] segments。Segment 繼承 ReentrantLock,是一個小型 Hash 表,擁有獨立鎖。HashEntry:key、hash、next 為 final,value 為 volatile,保證不可變性與可見性。final int segmentMask; // 段索引掩碼
final int segmentShift; // 段索引位移
final Segment[] segments;
段數組為 final,成員也為 final,按固定順序獲取鎖避免死鎖。
final Segment segmentFor(int hash) {
return segments[(hash >>> segmentShift) & segmentMask];
}
鎖定段,檢查擴容,定位桶,遍歷鏈表若 key 存在則更新 value,否則頭插法創建新節點,最後寫入 count(volatile)保證可見性。
鎖定段,定位節點。因 HashEntry 不可變,刪除需克隆前驅節點,尾節點指向被刪節點的 next。修改 modCount、count。
讀取 count(volatile)建立 happens-before,遍歷鏈表(next 為 final)。若讀到 value==null,加鎖重讀防止指令重排導致的可見性問題。
size()、containsValue() 需按順序鎖定所有段,操作完按順序釋放,利用 modCount 檢測遍歷過程中是否有修改,若有則重試。
大數組多線程共享時可考慮分段鎖思想;數據庫事務分離、分表同理。