CountDownLatch 是 Java 并发包中用于线程同步的一次性工具,通过维护可递减的计数器实现“等待一组操作完成”;初始化后调用 countDown() 减计数,await() 阻塞直至计数归零,不可重置。

CountDownLatch 是 Java 并发包中用于协调多个线程执行顺序的核心工具,它不控制线程的并发数量,而是让一个或多个线程等待其他线程完成指定任务后再继续执行。
CountDownLatch 的核心机制
CountDownLatch 内部维护一个计数器(int 类型),初始化时指定初始值。调用 countDown() 方法会使计数器减 1;调用 await() 的线程会阻塞,直到计数器变为 0 或被中断。一旦计数器归零,所有因 await() 阻塞的线程将被唤醒,且后续再调用 await() 将立即返回——CountDownLatch 是一次性使用的,不可重置。
典型使用场景
适用于“等待一组操作全部完成”这类同步需求:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 主线程启动多个子任务(如批量请求、数据预加载),需等全部完成后再汇总结果
- 测试中模拟多线程并发启动(如“同时开始”压测)
- 服务初始化阶段,等待多个依赖模块就绪后才对外提供服务
基本用法示例
以下代码演示主线程等待 3 个子线程完成工作:
立即学习“Java免费学习笔记(深入)”;
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 模拟耗时操作
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " 完成");
latch.countDown(); // 计数器减1
}).start();
}
try {
latch.await(); // 主线程阻塞,直到计数器为0
System.out.println("所有子任务已完成,继续执行...");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
注意事项与常见误区
使用时需注意几个关键点:
- 不要在 await() 后忽略中断处理:若线程被中断,await() 抛出 InterruptedException,应恢复中断状态或合理处理
- countDown() 可在任意线程中多次调用,但总数超过初始值不会出错,只是提前释放等待线程
- 不能替代 CyclicBarrier:后者支持重复使用,适合多轮协作;CountDownLatch 更适合“一次性等待”
- 避免在 countDown() 前发生异常导致漏调用——可配合 finally 块确保执行

















