countdownlatch计数器归零时,所有await()阻塞线程(含主线程)自动唤醒;主线程应调用await()挂起等待,不可轮询getcount();需捕获interruptedexception并恢复中断状态。

当 CountDownLatch 的计数器减到 0 时,所有因 await() 而阻塞的线程(包括主线程)会自动被唤醒,无需手动通知。
主线程如何等待 CountDownLatch 归零
主线程调用 latch.await() 后会进入阻塞状态,直到内部计数器变为 0,或被中断、超时。这是最常用且推荐的方式:
- 调用
await()会挂起当前线程(比如主线程),不消耗 CPU - 一旦其他线程调用足够次数的
countDown()使计数归零,JVM 自动唤醒所有等待线程 - 唤醒后,
await()方法返回,主线程继续执行后续代码
注意异常和中断处理
await() 可能抛出 InterruptedException,必须显式处理:
- 如果主线程在等待时被其他线程中断,会立即抛出该异常并退出阻塞
- 建议在 catch 块中恢复中断状态:
Thread.currentThread().interrupt(); - 不建议直接吞掉异常或忽略中断信号
别用 busy-wait(轮询)替代 await
错误做法:用 while 循环不断调用 getCount() 判断是否为 0 —— 这是忙等待,浪费 CPU,且无法保证及时性:
-
getCount()是非阻塞方法,不能触发唤醒机制 - 即使计数已为 0,轮询线程也不会“被唤醒”,只是下次检查碰巧看到结果
- 违背
CountDownLatch的设计初衷,也失去线程协作的意义
一个典型使用示例
主线程启动多个子任务,等它们全部完成后再继续:
CountDownLatch latch = new CountDownLatch(3);
// 启动 3 个子线程,每个完成后调用 latch.countDown()
new Thread(() -> { /* work */ latch.countDown(); }).start();
new Thread(() -> { /* work */ latch.countDown(); }).start();
new Thread(() -> { /* work */ latch.countDown(); }).start();
<p>// 主线程在此阻塞,直到 latch 计数变为 0
latch.await(); // ✅ 正确:自动唤醒
System.out.println("所有子任务已完成");</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











