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

java.util.concurrent 併發集合核心類詳解(上)

     編輯:Java 相關知識

併發集合:多線程編程的利器

Java 5 引入的 java.util.concurrent 包含多個高效解決常見併發問題的集合類,卻常被註解與泛型的光芒掩蓋。本文介紹五大核心類,助你擺脫手寫同步代碼的泥潭。

1. TimeUnit:時間單位的領域模型

雖非集合,但極大提升代碼可讀性。枚舉涵蓋 NANOSECONDS 至 DAYS,提供轉換方法:TimeUnit.HOURS.toMillis(1)。API 簽名統一使用 (timeout, TimeUnit),徹底擺脫「毫秒霸權」,意圖顯性化。

2. CopyOnWriteArrayList:讀多寫少的最佳選

痛點: 同步 ArrayList 導致讀讀互斥;複製數組成本高。

方案: 寫操作(add/set/remove)複製全新數組,讀操作直接訪問不可變快照,**零同步開銷**。適用場景:事件監聽器列表、配置緩存——頻繁遍歷,極少修改。

List<Listener> listeners = new CopyOnWriteArrayList<>();
// 遍歷無需加鎖
for (Listener l : listeners) l.onEvent(event);

3. BlockingQueue:生產者-消費者模式的標準化

FIFO 隊列,核心特性:空隊列取元素阻塞、滿隊列放元素阻塞。徹底替代手寫 wait()/notifyAll() 的 Guarded Blocks 模式。

ArrayBlockingQueue:有界隊列,支援公平策略(FIFO 獲取鎖),避免線程飢餓。

代碼對比: 生產者 put()、消費者 take(),簡潔無誤。支援 offer/poll(timeout) 避免無限等待。

4. ConcurrentMap:消除 Map 併發陷阱

經典 Bug: if (!map.containsKey(k)) map.put(k, v); 在同步 Map 下仍有競態條件(檢查與放入非原子)。

解決: ConcurrentMap.putIfAbsent(k, v) 原子完成「檢查並放入」。另有 remove(k, v)、replace(k, old, new) 等複合原子操作,ConcurrentHashMap 為高效實現。

5. SynchronousQueue:零容量的直接移交

特殊的 BlockingQueue:**無內部容量**,put() 必須等待 take(),反之亦然。實現線程間單元素直接交接,語義同 Ada/CSP 的「會合通道」。

代碼結構與 ArrayBlockingQueue 幾乎相同,但更輕量,適合「生產即消費」場景,避免隊列積壓與內存佔用。

總結

五大類覆蓋:時間建模(TimeUnit)、讀多寫少列表(CopyOnWriteArrayList)、生產消費隊列(BlockingQueue)、安全 Map(ConcurrentMap)、直接移交(SynchronousQueue)。下篇將探討鎖、同步器與原子變量等進階工具。

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