Java 5 引入的 ConcurrentHashMap(CHM)是 java.util.concurrent 套件的核心成員,旨在取代 Hashtable 和 Collections.synchronizedMap()。傳統方案透過鎖定整個 Map 確保線程安全,嚴重限制並發效能;CHM 採用 分段鎖 技術,將資料結構切分為多個 Segment,預設 16 個段落,各自擁有獨立鎖,理論上支援 16 個寫入執行緒同時操作,讀取操作則完全無鎖,大幅提升吞吐量。
put()、remove()、putAll()、clear() 僅鎖定目標段落。keySet() 回傳的 iterator 為 fail-safe,遍歷過程不拋出 ConcurrentModificationException,但可能看不到最新寫入。HashMap 不同,CHM 禁止 null key/value,避免歧義。ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) 允許自訂段落數;寫入執行緒較少時建議降低級別以節省空間。傳統「檢查後放入」模式在 CHM 失效:
synchronized(map) {
if (map.get(key) == null) return map.put(key, value);
else return map.get(key);
}
因 CHM 僅鎖定段落,執行緒 A put(k,v1) 時,執行緒 B get(k) 可能讀到 null,導致值被覆蓋。正確做法直接呼叫 map.putIfAbsent(key, value),該方法原子完成「不存在則放入」,無需外部同步,保持高並發優勢。
CHM 適合 讀多寫少 場景(如快取初始化後高頻讀取)。若寫入執行緒數 ≥ 讀取執行緒,因鎖競爭與記憶體屏障開銷,效能反而不如 Hashtable 或同步 Map。記住:CHM 犧牲了「強一致性」換取高並發,若業務要求嚴格序列化存取,請回歸傳統同步方案。
掌握上述特性,即能在高併發系統中正確、高效地運用 ConcurrentHashMap。