countdownlatch 通过倒计时和阻塞等待协调多线程并发启动与汇合:启动时用单次 latch 实现门闩式同时开始;汇合时用 n 次 countdown 配 await 等待全部完成;其为一次性工具,需在 finally 中调用 countdown 并注意超时控制。

CountDownLatch 是 Java 并发编程中用于协调多个线程等待某组操作完成的同步工具,它本身不直接实现“并发分支”,但能高效统一控制多个并发分支的启动与汇合点——核心在于“倒计时”和“阻塞等待”两个行为。
用 CountDownLatch 控制并发分支的启动(同时开始)
当多个线程需要从同一时刻开始执行(比如压测、模拟并发请求),可借助 CountDownLatch 实现“门闩式”释放:
- 主线程创建 CountDownLatch(1),先调用 await() 阻塞自身;
- 各分支线程启动后,立即调用 await() 等待同一 latch;
- 所有线程就位后,主线程调用 countDown(),所有 await() 同时返回,实现真正并发启动。
注意:必须确保所有分支线程在主线程 countDown() 前已进入 await(),否则可能漏掉部分线程。常用做法是用另一个 latch(如 CountDownLatch(startSignal))确保就绪通知。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
用 CountDownLatch 控制并发分支的汇合(统一收尾)
这是最常见用法:主线程派生多个子任务,需等全部完成后再继续后续逻辑:
- 初始化 CountDownLatch latch = new CountDownLatch(n),n 为分支数量;
- 每个分支线程执行完自己的任务后,调用 latch.countDown();
- 主线程调用 latch.await(),会阻塞直到内部计数归零,再继续执行汇总、清理等操作。
例如:开启 5 个线程分别下载文件,主线程 await() 后统一校验 MD5 或合并结果,无需轮询或 sleep。
关键细节与避坑提醒
CountDownLatch 是一次性工具,计数归零后不可重置,重复 await() 会立即返回,重复 countDown() 无影响但无意义:
- 不要在分支线程中捕获异常后忽略 countDown(),否则主线程可能永久阻塞;建议 finally 块中调用;
- await() 支持超时(await(long, TimeUnit)),避免因某个分支异常挂起整个流程;
- 它不关心线程身份或执行结果,只管“是否调用了 countDown()”,错误处理需配合 Future、异常收集等机制;
- 若需多次复用同步点,应改用 CyclicBarrier。
简单示例:3 个并发分支,统一等待完成
// 主线程
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i
new Thread(() -> {
try {
// 模拟分支任务
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
latch.countDown(); // 必须确保执行
}
}).start();
}
latch.await(); // 主线程在此等待全部完成
System.out.println("所有分支执行完毕");
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










