Mastering CountDownLatch and CyclicBarrier: Java Concurrency Made Simple
CountDownLatch and CyclicBarrier are two essential Java synchronization tools from java.util.concurrent, enabling threads to coordinate tasks; this guide explains their concepts, usage with code examples, advantages, disadvantages, and key differences, helping developers choose the right tool for thread coordination.
CountDownLatch (Countdown Latch)
Introduction
CountDownLatch is a counter that allows one or more threads to wait until other threads have completed their operations. The counter is initialized with a positive integer; each time a thread finishes its work it calls countDown() to decrement the counter. When the counter reaches zero, all threads waiting on await() are released.
Usage Example
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
int workerCount = 3;
CountDownLatch latch = new CountDownLatch(workerCount);
// Simulate 3 workers
for (int i = 0; i < workerCount; i++) {
final int workerId = i;
new Thread(() -> {
try {
System.out.println("Worker " + workerId + " 开始工作");
Thread.sleep(1000); // simulate work
System.out.println("Worker " + workerId + " 完成工作");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// Work done, decrement counter
latch.countDown();
System.out.println("Worker " + workerId + " 休息了");
}
}).start();
}
// Main thread waits for all workers
latch.await();
System.out.println("所有工作完成");
}
} Worker 0 开始工作
Worker 2 开始工作
Worker 1 开始工作
Worker 1 完成工作
Worker 1 休息了
Worker 2 完成工作
Worker 2 休息了
Worker 0 完成工作
Worker 0 休息了
所有工作完成The main thread blocks on await() until the latch count reaches zero. Each worker calls countDown() after finishing, which does not block the calling thread.
Note: Calling CountDownLatch.countDown() does not block the current thread; execution continues immediately.
Pros and Cons
Pros:
Provides a simple way to wait for a group of threads to finish.
One‑time use; after the count reaches zero it cannot be reset.
Cons:
Cannot be reused; a new CountDownLatch instance is required for subsequent waits.
CyclicBarrier (Cyclic Barrier)
Introduction
CyclicBarrier is another common synchronization tool that lets a set of threads wait for each other until all have reached a common barrier point, then they proceed together. Unlike CountDownLatch, CyclicBarrier is reusable: after all threads reach the barrier, the count resets automatically.
Usage Example
The following example demonstrates a game‑matching scenario where a game starts only when a fixed number of players have joined.
public class CyclicBarrierTest {
private static final int PLAYERS_PER_GAME = 5;
public static void main(String[] args) {
AtomicInteger gameCount = new AtomicInteger(1);
CyclicBarrier matchBarrier = new CyclicBarrier(PLAYERS_PER_GAME, () -> {
System.out.println("===== 第 " + gameCount.getAndIncrement() + " 局游戏开始!=====");
});
ExecutorService playerPool = Executors.newFixedThreadPool(10);
for (int i = 1; i <= 10; i++) {
final int playerId = i;
playerPool.submit(() -> {
try {
Thread.sleep(new Random().nextInt(1000)); // random join delay
System.out.println("玩家 " + playerId + " 加入匹配队列");
int currentGame = gameCount.get();
matchBarrier.await(); // wait for other players
System.out.println("玩家 " + playerId + " 进入第 " + currentGame + " 局游戏");
Thread.sleep(2000); // simulate game
System.out.println("玩家 " + playerId + " 完成第 " + currentGame + " 局游戏");
} catch (Exception e) {
e.printStackTrace();
}
});
}
playerPool.shutdown();
try {
playerPool.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} 玩家 2 加入匹配队列
玩家 9 加入匹配队列
玩家 4 加入匹配队列
玩家 5 加入匹配队列
玩家 6 加入匹配队列
===== 第 1 局游戏开始!=====
玩家 6 进入第 1 局游戏
玩家 2 进入第 1 局游戏
玩家 9 进入第 1 局游戏
玩家 4 进入第 1 局游戏
玩家 5 进入第 1 局游戏
玩家 10 加入匹配队列
玩家 8 加入匹配队列
玩家 7 加入匹配队列
玩家 1 加入匹配队列
玩家 3 加入匹配队列
===== 第 2 局游戏开始!=====
玩家 3 进入第 2 局游戏
玩家 10 进入第 2 局游戏
玩家 8 进入第 2 局游戏
玩家 1 进入第 2 局游戏
玩家 7 进入第 2 局游戏
玩家 4 完成第 1 局游戏
玩家 6 完成第 1 局游戏
玩家 5 完成第 1 局游戏
玩家 2 完成第 1 局游戏
玩家 9 完成第 1 局游戏
玩家 3 完成第 2 局游戏
玩家 10 完成第 2 局游戏
玩家 1 完成第 2 局游戏
玩家 8 完成第 2 局游戏
玩家 7 完成第 2 局游戏Pros and Cons
Pros:
CyclicBarrier can be reused across multiple synchronization cycles.
Allows execution of a barrier action (callback) when all threads reach the barrier.
Cons:
If a waiting thread is interrupted or throws an exception, other threads may be blocked indefinitely.
Key Differences Between CountDownLatch and CyclicBarrier
Both are synchronization utilities, but they differ in reusability and usage patterns:
Reusability: CountDownLatch is one‑time use; after the count reaches zero it cannot be reset. CyclicBarrier is reusable; the count resets after each barrier point.
Purpose: CountDownLatch is suited for a thread waiting for other threads to finish (e.g., start a service after initialization). CyclicBarrier fits scenarios where a group of threads must wait for each other at multiple stages (e.g., parallel computation phases).
Blocking Behavior: After calling countDown(), the thread continues without blocking. In contrast, await() on a CyclicBarrier blocks the calling thread until all parties arrive.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Xuanwu Backend Tech Stack
Primarily covers fundamental Java concepts, mainstream frameworks, deep dives into underlying principles, and JVM internals.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
