countdownlatch 的核心是“等待计数归零”,通过 await() 阻塞线程直至 countdown() 将初始正整数计数器减至 0;计数器不可重置,不感知任务成败,仅统计调用次数。

CountDownLatch 的核心在于“等待计数归零”,它不控制线程内部执行逻辑,而是让某些线程**阻塞等待**,直到其他线程完成指定任务、将计数器减到 0,才被唤醒继续执行。
计数器初始化决定等待粒度
构造时传入的 int 值是初始计数,代表“需要等待完成的任务数量”。这个值一旦设定就不能修改,且必须大于 0。比如:
- new CountDownLatch(1):常用于“一等一”,如主线程等子线程初始化完毕;
- new CountDownLatch(5):适合协调 5 个并行任务,全部调用 countDown() 后才放行;
- 若误设为 0,await() 会直接返回,不阻塞——这在测试或预热场景下有时有意为之。
countDown() 是唯一减法操作
每次调用 countDown(),计数器原子性地减 1。它不要求调用者是同一线程,多个线程可分别触发,也允许同一线程多次调用(只要未归零)。注意:
- 超过初始值的多次调用不会报错,但归零后继续调用无效(计数保持 0);
- 没有“加回”或重置方法,用完即弃,需重新 new 实例;
- 它不关联具体任务成败——即使某任务失败,只要调用了 countDown(),就算“完成一次”。业务上需自行配合异常处理。
await() 阻塞直到归零或超时
调用 await() 的线程会挂起,直到计数为 0 或被中断。支持带超时的版本,避免无限等待:
- await():永久等待,除非计数归零或线程被 interrupt;
- await(3, TimeUnit.SECONDS):最多等 3 秒,返回 true 表示成功等到归零,false 表示超时;
- 超时后计数器仍为正数,后续再调用 await() 仍会阻塞,除非有更多 countDown()。
典型使用模式:启动屏障与结束屏障
常见两类场景:
- 启动屏障:主线程创建 CountDownLatch(1),启动多个工作线程,各线程先 await();主线程做完准备后调用 countDown(),所有工作线程同时开始执行;
- 结束屏障:主线程创建 CountDownLatch(N),启动 N 个任务,每个任务结尾调用 countDown();主线程 await() 等待全部完成后再汇总结果。
不复杂但容易忽略细节。











