Java 的?java.util.concurrent
(簡稱 JUC)包是 JDK 5 及以后引入的并發編程工具包,旨在解決傳統線程模型(如?synchronized
、wait/notify
)的局限性,提供更靈活、高效、可擴展的并發編程組件。它極大簡化了多線程開發,是 Java 并發編程的核心工具。
一、JUC 包的核心作用
傳統并發編程依賴?synchronized
?關鍵字和?Object
?的?wait()
/notify()
?方法,存在靈活性低(鎖無法中斷、無法超時)、效率有限(重量級鎖)等問題。JUC 包通過以下方式改進:
- 提供更細粒度的同步控制(如可中斷鎖、超時鎖);
- 內置線程池管理,避免頻繁創建銷毀線程的開銷;
- 提供線程安全的并發集合(替代?
HashMap
?等線程不安全的集合); - 封裝常用并發工具(如計數器、信號量),減少重復開發。
二、JUC 核心組件分類
JUC 包內容豐富,可分為以下幾大模塊:
1. 線程池框架(Executor 體系)
線程池是管理線程的容器,避免頻繁創建 / 銷毀線程的性能損耗,核心接口和類如下:
- Executor:最頂層接口,定義了?
execute(Runnable)
?方法,用于執行任務。 - ExecutorService:繼承?
Executor
,增加了線程池生命周期管理(如?shutdown()
?關閉線程池、submit()
?提交帶返回值的任務)。 - ThreadPoolExecutor:線程池的核心實現類,需關注 7 個核心參數:
corePoolSize
:核心線程數(始終存活的線程);maximumPoolSize
:最大線程數(核心線程 + 臨時線程的上限);keepAliveTime
:臨時線程空閑時的存活時間;workQueue
:任務等待隊列(核心線程滿時,新任務進入隊列);threadFactory
:創建線程的工廠;handler
:任務拒絕策略(隊列和最大線程都滿時的處理方式)。
- Executors:線程池工具類,提供便捷的線程池創建方法(如?
newFixedThreadPool
?固定大小線程池、newCachedThreadPool
?緩存線程池),但實際開發中建議直接使用?ThreadPoolExecutor
?自定義參數(避免資源耗盡風險)。
2. 并發集合(線程安全的容器)
傳統集合(如?HashMap
、ArrayList
)線程不安全,JUC 提供了專門的并發集合,解決多線程讀寫安全問題:
并發集合類 | 對應傳統集合 | 特點與適用場景 |
---|---|---|
ConcurrentHashMap | HashMap | 線程安全的哈希表,JDK 1.8 用?CAS + synchronized ?實現(替代分段鎖),支持高并發讀寫。 |
CopyOnWriteArrayList | ArrayList | 讀寫分離,寫操作時復制底層數組,適合讀多寫少場景(如配置緩存)。 |
CopyOnWriteArraySet | HashSet | 基于?CopyOnWriteArrayList ?實現,原理同上。 |
ConcurrentLinkedQueue | LinkedList (隊列) | 無鎖并發隊列,基于 CAS 實現,適合高并發場景的隊列操作。 |
BlockingQueue | - | 阻塞隊列,提供?put() (滿時阻塞)和?take() (空時阻塞)方法,常用于生產者 - 消費者模型。實現類有?ArrayBlockingQueue 、LinkedBlockingQueue ?等。 |
3. 同步工具類(控制線程協作)
用于協調多個線程的執行順序或資源訪問,核心工具包括:
Lock 與 Condition:替代?
synchronized
?和?wait()/notify()
?的更靈活同步方式。Lock
?接口:定義?lock()
(獲取鎖)、tryLock(long, TimeUnit)
(超時獲取鎖)、unlock()
(釋放鎖)等方法,實現類?ReentrantLock
(可重入鎖)是最常用的。Condition
:通過?Lock.newCondition()
?創建,提供?await()
(等待)、signal()
(喚醒單個)、signalAll()
(喚醒所有),可實現多個條件隊列(比?Object
?的單一等待隊列更靈活)。
Semaphore(信號量):控制同時訪問資源的線程數,類似 “許可證” 機制。例如:
Semaphore semaphore = new Semaphore(3); // 允許3個線程同時訪問 semaphore.acquire(); // 獲取許可證(若滿則阻塞) // 訪問資源... semaphore.release(); // 釋放許可證
CountDownLatch(倒計時器):等待多個線程完成后再執行主線程。例如:
CountDownLatch latch = new CountDownLatch(5); // 計數5 // 子線程執行完后調用 latch.countDown();(計數-1) latch.await(); // 主線程阻塞,直到計數為0
CyclicBarrier(循環屏障):讓多個線程到達 “屏障” 后等待,全部到達后一起繼續執行(可重復使用)。例如:
CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("所有線程就緒,開始執行")); // 每個線程執行到 barrier.await() 時等待,直到3個線程都到達
4. 原子類(Atomic 系列)
基于 CAS(Compare-And-Swap,比較并交換)操作,提供線程安全的原子性變量更新,避免使用?synchronized
?的開銷。核心類:
- 基本類型:
AtomicInteger
、AtomicLong
、AtomicBoolean
(提供?getAndIncrement()
?原子自增等方法)。 - 引用類型:
AtomicReference
(原子更新對象引用)、AtomicStampedReference
(解決 CAS 的 ABA 問題,帶版本號)。 - 數組類型:
AtomicIntegerArray
(原子更新數組元素)。
示例:
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet(); // 原子自增(替代 count++,線程安全)
5. 其他重要組件
- Future 與 Callable:
Callable
?是帶返回值的任務(類似?Runnable
?但有返回值),Future
?用于獲取?Callable
?的執行結果。FutureTask
?是?Future
?的實現類,可包裝?Callable
?并作為任務提交給線程池。 - AQS(AbstractQueuedSynchronizer):JUC 許多組件的底層基礎(如?
ReentrantLock
、Semaphore
),通過維護一個 “同步狀態” 和 “雙向阻塞隊列” 實現同步控制,核心是?acquire()
(獲取資源)和?release()
(釋放資源)。
三、JUC 的核心優勢
- 更高的靈活性:如?
Lock
?支持超時、中斷,Condition
?支持多條件等待。 - 更好的性能:如?
ConcurrentHashMap
?比?Hashtable
?效率更高,原子類基于 CAS 避免鎖開銷。 - 更豐富的功能:內置線程池、阻塞隊列、信號量等工具,簡化并發編程。
總結
JUC 包是 Java 并發編程的 “瑞士軍刀”,涵蓋了線程管理、同步控制、并發容器等核心能力。掌握 JUC 組件的原理和適用場景,能有效解決多線程開發中的安全性、性能和可維護性問題,是中高級 Java 開發者的必備知識。