CountDownLatch的核心作用是让线程等待一组操作全部完成后再继续执行;它通过倒计时机制实现同步,需确保每个子任务在finally中调用countDown(),且不可重置,适用于批量任务等待、多阶段启动和并发压测等场景。

CountDownLatch 的核心作用是让一个或多个线程“等齐再动”——即等待一组操作全部完成,计数归零后才继续执行。它不参与任务调度或结果处理,只做可靠的倒计时同步,用对了逻辑清晰,用错了容易卡死或提前放行。
主线程等待多子任务完成
这是最常见场景,比如批量查库、并行下载、微服务聚合调用。关键在于确保每个子任务无论成功或异常,都必须触发 countDown()。否则计数器无法归零,主线程将永久阻塞。
- 推荐在子任务的 finally 块中调用 countDown()
- 初始化时传入任务总数,例如
new CountDownLatch(5)表示等 5 个任务 - 主线程调用 await() 阻塞等待;建议使用带超时的 await(30, TimeUnit.SECONDS),避免下游故障导致雪崩式挂起
多阶段协同启动
适用于服务初始化场景,如配置加载、连接池构建、缓存预热三步并行准备,全部就绪后再触发监听器启动。此时 CountDownLatch 是“就绪门控”,不是“执行门控”——它控制的是“是否准备好”,而非“是否开始执行”。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 各模块启动线程各自完成本职工作后调用 countDown()
- 主线程在所有模块启动完成后,统一调用 await() 等待就绪信号
- 避免把耗时操作放在 await() 后面才启动,否则失去并行意义
并发压测统一发令
模拟高并发请求时,需让 N 个线程“同时出发”。常用双 latch 模式:一个控制起跑(startLatch),一个控制收尾(doneLatch)。
立即学习“Java免费学习笔记(深入)”;
- startLatch 初始化为 1,所有线程先 await() 卡在起跑线
- 主线程完成准备后调用 startLatch.countDown(),瞬间唤醒全部线程
- doneLatch 初始化为线程总数,每个线程执行完任务后 countDown()
- 主线程最后 doneLatch.await() 等待全部响应结束
避坑要点与替代选择
CountDownLatch 是一次性工具,计数归零后不可重置。若需循环使用(比如定时任务多次等待),应改用 CyclicBarrier。
- 不要在同一个线程里反复调用 await() 期待重用——它会立即返回,失去等待效果
- countDown() 是原子操作,可安全在多线程中频繁调用,无需额外同步
- 避免漏调 countDown();也避免无谓多调(虽不影响结果,但语义混乱)
- 不适用于需要响应中断的精细控制场景,此时可结合 CompletableFuture 或 Phaser


















