CountDownLatch 是一個同步計數器,構造時指定計數初始值。每調用一次 countDown() 計數減 1,當計數歸零時,所有調用 await() 等待的線程被釋放繼續執行。常用於「主線程等待多個子線程完成」或「多線程同步起跑」場景。
CountDownLatch(int count):構造器,設置初始計數void countDown():計數減 1,計數歸零喚醒等待線程void await():阻塞當前線程,直到計數歸零boolean await(long timeout, TimeUnit unit):帶超時等待long getCount():獲取當前計數值public class RaceSimulation {
private static final int PLAYER_COUNT = 5;
public static void main(String[] args) throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1); // 發令槍
CountDownLatch finishSignal = new CountDownLatch(PLAYER_COUNT); // 終點計數
ExecutorService executor = Executors.newFixedThreadPool(PLAYER_COUNT);
for (int i = 1; i <= PLAYER_COUNT; i++) {
final int playerNo = i;
executor.submit(() -> {
try {
startSignal.await(); // 等待發令
Thread.sleep((long) (Math.random() * 1000)); // 模擬跑步時間
System.out.println("選手 " + playerNo + " 到達終點");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
finishSignal.countDown(); // 到達終點計數
}
});
}
System.out.println("比賽開始!");
startSignal.countDown(); // 發令
finishSignal.await(); // 主線程等待所有人到達
System.out.println("比賽結束!");
executor.shutdown();
}
}
public class ServiceInitializer {
private final CountDownLatch latch;
private final List<Service> services = new ArrayList<>();
public ServiceInitializer(int serviceCount) {
this.latch = new CountDownLatch(serviceCount);
}
public void addService(Service service) {
services.add(service);
new Thread(() -> {
try {
service.init(); // 耗時初始化
} finally {
latch.countDown();
}
}).start();
}
public void waitForAllReady() throws InterruptedException {
latch.await(); // 阻塞直到所有服務就緒
System.out.println("所有服務初始化完成");
}
}
CountDownLatch 一次性計數,不可重置。若需循環同步(如多輪迭代計算),請使用 CyclicBarrier 或 Phaser。
countDown() 必須在 finally 塊調用,防止異常導致計數不減造成永久阻塞。countDown() 的次數,否則會過早釋放或永久等待。getCount() 僅供監控調試,不用於同步控制邏輯。基於 AbstractQueuedSynchronizer (AQS) 共享鎖模式:
countDown() → releaseShared(1) 嘗試釋放共享鎖await() → acquireSharedInterruptibly(1) 獲取共享鎖,state>0 時入隊阻塞CountDownLatch 是輕量級同步工具,專為「一組線程等待另一組線程完成」設計。掌握其計數語義與 AQS 原理,能優雅解決並行任務協調、服務啟動同步、分階段計算等核心並發問題。