CountDownLatch 是 Java 并发包中用于线程协调的倒计数同步工具,初始化指定计数值,countDown() 递减,await() 阻塞直至归零;它不可重置,非锁机制,适用于主线程等待多任务完成等场景。

CountDownLatch 是 Java 并发包(java.util.concurrent)中一个轻量级的同步辅助类,用于让一个或多个线程等待,直到其他线程完成一组操作。它的核心是“倒计数”机制:初始化时指定一个计数值,每次调用 countDown() 方法减 1;当计数变为 0 时,所有因 await() 阻塞的线程被唤醒,继续执行。
理解 CountDownLatch 的基本用法
它不是锁,也不控制临界区访问,而是协调线程执行顺序的“门栓”。典型场景包括:
- 主线程等待多个子任务全部完成后再汇总结果
- 多线程预热资源,全部就绪后统一开始业务逻辑
- 测试中模拟并发到达、验证线程间协作行为
创建并初始化 CountDownLatch
构造时传入初始计数值,这个值代表“需要等待完成的事件数量”:
CountDownLatch latch = new CountDownLatch(3); // 表示要等 3 个事件完成
注意:计数值只能设一次,不可重置(需重用请换新实例)。
立即学习“Java免费学习笔记(深入)”;
在工作线程中调用 countDown()
每个完成任务的线程调用 countDown(),减少计数。该方法是线程安全的,可被任意线程多次调用(但超出初始值无意义):
new Thread(() -> {
doWork();
latch.countDown(); // 完成一件事,计数减一
}).start();
即使某个线程异常退出,也应确保 countDown() 被调用(建议放在 finally 块中)。
在等待线程中调用 await()
调用 await() 的线程会阻塞,直到计数归零或被中断:
try {
latch.await(); // 可选带超时:latch.await(5, TimeUnit.SECONDS)
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// 处理中断,如取消后续操作
}
一旦计数为 0,所有等待线程被同时唤醒;await() 返回后,后续代码才执行。
常见误区与注意事项
避免把 CountDownLatch 当作循环屏障(那是 CyclicBarrier 的职责);它是一次性工具,计数归零后 await() 不再阻塞,countDown() 仍可调用但无效。若需重复使用,请考虑 CyclicBarrier 或手动新建实例。



















