首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 並發編程:ConcurrentHashMap 原理深度分析

     編輯:Java 相關知識

背景

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

結構解析

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];
}

Put 操作

鎖定段,檢查擴容,定位桶,遍歷鏈表若 key 存在則更新 value,否則頭插法創建新節點,最後寫入 count(volatile)保證可見性。

Remove 操作

鎖定段,定位節點。因 HashEntry 不可變,刪除需克隆前驅節點,尾節點指向被刪節點的 next。修改 modCount、count。

Get 操作(無鎖)

讀取 count(volatile)建立 happens-before,遍歷鏈表(next 為 final)。若讀到 value==null,加鎖重讀防止指令重排導致的可見性問題。

跨段操作

size()、containsValue() 需按順序鎖定所有段,操作完按順序釋放,利用 modCount 檢測遍歷過程中是否有修改,若有則重試。

應用場景

大數組多線程共享時可考慮分段鎖思想;數據庫事務分離、分表同理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved