CyclicBarrier(循環柵欄)讓一組線程互相等待,直到所有線程都到達屏障點,然後同時繼續執行。與 CountDownLatch 不同,它強調「多線程互相等待,缺一不可」,且可重用。
CyclicBarrier(int parties):建構子,指定攔截線程數CyclicBarrier(int parties, Runnable barrierAction):攔截動作版本,所有線程到達後先執行 barrierActionint await():到達屏障點等待,返回到達序號(0 為最後到達)int await(long timeout, TimeUnit unit):帶超時等待void reset():重置柵欄,可重用boolean isBroken():檢查是否處於損壞狀態10 人春遊,約定所有人到達集合點才能一起出發。每個人到達時間不同,必須等待最後一人。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class Tourist implements Runnable {
private final int id;
private final CyclicBarrier barrier;
public Tourist(int id, CyclicBarrier barrier) {
this.id = id;
this.barrier = barrier;
}
@Override
public void run() {
try {
// 模擬不同到達時間
Thread.sleep((long) (Math.random() * 3000));
System.out.println(id + " 號遊客到達集合點,等待其他人...");
int arrivalOrder = barrier.await(); // 到達屏障點等待
System.out.println(id + " 號遊客是第 " + (arrivalOrder + 1) + " 個到達的");
} catch (InterruptedException | BrokenBarrierException e) {
Thread.currentThread().interrupt();
System.err.println(id + " 號遊客行程中斷:" + e.getMessage());
}
}
}
public class SpringOuting {
public static void main(String[] args) {
int touristCount = 10;
// 攜帶攔截動作:所有人到齊後自動執行
CyclicBarrier barrier = new CyclicBarrier(touristCount, () -> {
System.out.println("======== 所有人到齊,一起出發!========");
});
for (int i = 1; i <= touristCount; i++) {
new Thread(new Tourist(i, barrier)).start();
}
}
}
3 號遊客到達集合點,等待其他人...
1 號遊客到達集合點,等待其他人...
7 號遊客到達集合點,等待其他人...
5 號遊客到達集合點,等待其他人...
2 號遊客到達集合點,等待其他人...
9 號遊客到達集合點,等待其他人...
4 號遊客到達集合點,等待其他人...
6 號遊客到達集合點,等待其他人...
10 號遊客到達集合點,等待其他人...
8 號遊客到達集合點,等待其他人...
======== 所有人到齊,一起出發!========
8 號遊客是第 1 個到達的
10 號遊客是第 2 個到達的
...
| 維度 | CountDownLatch | CyclicBarrier |
|---|---|---|
| 核心語義 | 倒數計數,等待事件完成 | 攔截匯合,等待線程到達 |
| 可重用性 | 不可重用(計數歸零失效) | 可重用(reset() 重置) |
| 線程角色 | 一線程等多線程 / 多線程等一線程 | 多線程互相等待(對等關係) |
| 攔截動作 | 不支援 | 支援 barrierAction(最後到達者執行) |
| 返回值 | 無 | 返回到達序號(0 為最後) |
| 異常處理 | 僅 InterruptedException | InterruptedException + BrokenBarrierException |
| 實現基礎 | AQS 共享鎖 | ReentrantLock + Condition |
// 多階段並行計算,每階段同步
CyclicBarrier barrier = new CyclicBarrier(workerCount, () -> {
// 階段合併結果
mergePhaseResults();
});
for (int phase = 0; phase < totalPhases; phase++) {
// 並行計算當前階段
executePhase(phase);
try {
barrier.await(); // 等待所有線程完成本階段
} catch (InterruptedException | BrokenBarrierException e) {
handleError(e);
}
}
await() 過程中被中斷/超時 → 所有等待線程拋出 BrokenBarrierExceptionreset() 恢復