CountDownLatch 是基于 AQS 共享模式实现的一次性同步辅助类,通过原子递减 state 计数器协调线程等待与释放,state 归零后不可重置。

CountDownLatch 是 Java 并发编程中协调线程执行顺序的轻量级工具,核心是“一个线程等多个线程做完再动”。它不涉及锁竞争,也不要求线程间共享数据,只靠一个递减计数器控制等待与释放。
CountDownLatch 的本质是什么
它是一个基于 AQS(AbstractQueuedSynchronizer)共享模式实现的一次性同步辅助类。构造时传入的整数就是 AQS 内部 state 变量的初始值,代表需等待的任务数量:
- 调用 await() 的线程会检查 state:若为 0,直接通过;否则进入 AQS 等待队列并挂起;
- 调用 countDown() 的线程会以 CAS 方式对 state 做原子减 1;
- 当 state 减至 0,AQS 会唤醒所有在 await 中阻塞的线程;
- state 归零后不可重置,CountDownLatch 不可复用(需重复用请选 CyclicBarrier)。
关键方法怎么用才不出错
三个常用方法看似简单,但细节决定是否稳定:
- await():阻塞当前线程,直到计数归零或被中断。建议搭配 try-catch 处理 InterruptedException;
- await(long, TimeUnit):带超时的等待,避免因某线程异常未调用 countDown() 导致永久阻塞;
- countDown():线程安全,可被任意线程多次调用,但只有使 state 从 1→0 的那一次才会触发唤醒;
- getCount():非阻塞读取当前剩余计数,适合日志、监控或调试,但不用于逻辑判断(因可能瞬间变化)。
典型实战场景与写法要点
不是所有“等线程结束”都该用 CountDownLatch,它适合单次、确定数量、无依赖关系的协作:
立即学习“Java免费学习笔记(深入)”;
- 主线程等子任务汇总:如启动 5 个下载线程,每个完成调用 countDown(),主线程 await() 后合并结果;
- 并发压测起点同步:初始化 100 个线程,全部调用 await() 阻塞,主线程 sleep 后 countDown() —— 所有线程瞬间并发执行,模拟秒杀入口;
- 服务启动检查:微服务启动时,DB 连接、缓存初始化、配置加载作为独立子任务,用 latch.await() 确保全部就绪后再开放 HTTP 接口;
- 注意:不要在循环中反复 new CountDownLatch,也不要在线程池任务里漏掉 countDown()(建议 finally 块中调用)。
和类似工具的区别要点
避免误用的关键,在于理解它的定位边界:
- vs Thread.join():join 只能等单个线程,且耦合强;CountDownLatch 支持 N 个线程任意组合、任意线程调用 countDown();
- vs CyclicBarrier:后者可重复使用、支持到达时执行回调(barrierAction),适合分阶段协同计算;
- vs Semaphore:后者控制并发数(资源许可),是“限流”,不是“等待完成”;
- vs CompletableFuture:后者面向异步编排,功能更重,CountDownLatch 更底层、更轻量、无回调逻辑。


















