countdownlatch用于线程同步,主线程await等待,子线程完成任务后必须在finally中调用countdown()递减计数器;初始化时需准确设置总数,计数器归零后不可重置,超时或中断需妥善处理。

CountDownLatch 是 Java 并发包中用于线程间同步的工具类,核心作用是让一个或多个线程等待其他线程完成一组操作后再继续执行。 它内部维护一个计数器,每次调用 countDown() 递减,当计数器归零时,所有因 await() 阻塞的线程被唤醒。主线程调用 await() 等待,子线程完成任务后调用 countDown(),是最典型的“等待全部完成”场景。
初始化 CountDownLatch 时指定子线程数量
构造时传入预期的子线程总数,这个数值必须准确——少设会导致主线程提前结束,多设则可能永久阻塞。
- 例如启动 3 个子线程处理不同数据,就 new CountDownLatch(3)
- 计数器不可重置,用完即弃;需重复使用应考虑 CyclicBarrier 或重新创建实例
子线程执行完任务后必须调用 countDown()
每个子线程在自身逻辑结束后(无论成功或异常),都应确保调用 countDown()。推荐放在 finally 块中,避免因异常跳过导致计数器无法归零。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 错误写法:只在 try 块里调用,catch 中遗漏
- 正确写法:在 finally 中调用,保证释放信号
- 即使子线程抛出异常,也要触发 countDown,否则主线程会一直 await
主线程调用 await() 等待所有子线程完成
主线程在启动所有子线程后,立即调用 latch.await()。该方法会阻塞当前线程,直到计数器变为 0 或被中断。
- 可选带超时的版本:
latch.await(10, TimeUnit.SECONDS),避免无限等待 - 若超时或被中断,await() 返回 false 或抛出 InterruptedException,需合理处理
- await() 返回后,可安全访问子线程产生的结果(建议用线程安全容器或 Future 收集)
结合 ExecutorService 使用更简洁可靠
配合线程池管理子线程,避免手动创建 Thread 对象,也便于统一异常处理和资源回收。
- 提交任务时,每个 Runnable/Callable 内部仍需负责 countDown()
- 线程池 shutdown 后,通常不再提交新任务,但 await 仍要等已有任务完成
- 注意:不要在 submit 的 lambda 中直接捕获并吞掉异常,否则可能掩盖问题且忘记 countDown
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










