並發工具類
概述
Java 提供了多種並發工具類,用於協調多個執行緒之間的同步操作。
Semaphore 信號量
Semaphore 是一種用於控制多個執行緒同時訪問共享資源的同步機制。它可以限制同時訪問的執行緒數量。

Semaphore 提供了兩個操作:
acquire(獲取)和 release(釋放)。當一個執行緒要訪問共享資源時,它需要先獲取信號量,如果信號量可用則獲取成功,否則它會被阻塞直到有其他執行緒釋放了信號量。SemaphoreExample.java
Semaphore semaphore = new Semaphore(3); // 最多允許 3 個執行緒同時訪問
// 獲取許可
semaphore.acquire();
try {
// 訪問共享資源
} finally {
// 釋放許可
semaphore.release();
}CountDownLatch 倒數門檻
CountDownLatch 是一種同步工具,它允許一個或多個執行緒等待直到其他一組執行緒完成它們的操作。

CountDownLatch 包含一個計數器,當計數器值為零時,等待的執行緒將被釋放。每當一個執行緒完成其工作時,它會將計數器減少一個數量。
CountDownLatchExample.java
CountDownLatch latch = new CountDownLatch(3);
// 工作執行緒
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 執行工作
System.out.println(Thread.currentThread().getName() + " 完成工作");
latch.countDown(); // 計數器減 1
}).start();
}
// 主執行緒等待
latch.await(); // 等待計數器歸零
System.out.println("所有工作完成");CyclicBarrier 循環屏障
CyclicBarrier 允許一組執行緒在特定的屏障點同步等待彼此,然後在所有執行緒都到達後繼續執行。

CyclicBarrier 可以重複使用,一旦所有執行緒都到達屏障點,它會重置以便下一次使用。
CyclicBarrierExample.java
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有執行緒都到達屏障點");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 到達屏障");
try {
barrier.await(); // 等待其他執行緒
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 繼續執行");
}).start();
}CountDownLatch vs CyclicBarrier
| 特性 | CountDownLatch | CyclicBarrier |
|---|---|---|
| 重複使用 | 不可以 | 可以 |
| 計數方式 | 倒數至零 | 等待所有執行緒到達 |
| 用途 | 等待一組事件完成 | 執行緒間相互等待 |
Exchanger 交換器
Exchanger 用於兩個執行緒之間交換資料的同步點。每個執行緒在 Exchanger 點上等待,直到另一個執行緒也到達,然後它們交換資料後繼續執行。

ExchangerExample.java
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
try {
String data = "資料 A";
String received = exchanger.exchange(data);
System.out.println("執行緒 1 收到: " + received);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
String data = "資料 B";
String received = exchanger.exchange(data);
System.out.println("執行緒 2 收到: " + received);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();Phaser 階段器
Phaser 提供了一種更靈活的同步機制,用於控制多階段執行的同步。它可以用於同步執行緒在多個階段之間的協調。

每個階段都可以包含任意數量的執行緒,並且當所有執行緒完成該階段時,才能進入下一個階段。Phaser 比 CyclicBarrier 更靈活,因為可以動態註冊和取消註冊參與者。
PhaserExample.java
Phaser phaser = new Phaser(3); // 3 個參與者
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 階段 1 完成");
phaser.arriveAndAwaitAdvance(); // 等待其他執行緒完成階段 1
System.out.println(Thread.currentThread().getName() + " 階段 2 完成");
phaser.arriveAndAwaitAdvance(); // 等待其他執行緒完成階段 2
System.out.println(Thread.currentThread().getName() + " 所有階段完成");
phaser.arriveAndDeregister(); // 完成並取消註冊
}).start();
}總結比較
| 工具類 | 用途 | 重複使用 | 動態參與者 |
|---|---|---|---|
| Semaphore | 限制同時訪問資源的執行緒數 | 是 | - |
| CountDownLatch | 等待一組事件完成 | 否 | 否 |
| CyclicBarrier | 執行緒間相互等待 | 是 | 否 |
| Exchanger | 兩執行緒間交換資料 | 是 | - |
| Phaser | 多階段同步 | 是 | 是 |