CountDownLatch
是 Java 并发工具类,基于计数器实现线程等待机制。通过 await()
阻塞线程直到计数器归零,countDown()
减少计数。常用于主线程等待多个子线程完成任务,或控制多线程同时启动。
一、核心功能
- 初始化计数器:创建时指定计数值(不可重置)。
- 线程阻塞 :调用
await()
的线程会阻塞,直到计数器归零。 - 计数递减 :子线程完成任务后调用
countDown()
,计数器减 1。
二、核心方法
方法 | 说明 |
---|---|
CountDownLatch(int count) |
构造方法,初始化计数器 |
void await() |
阻塞当前线程,直到计数器归零 |
boolean await(long timeout, TimeUnit unit) |
带超时的等待,超时后继续执行 |
void countDown() |
计数器减 1(线程安全) |
long getCount() |
获取当前计数值 |
三、典型使用场景
- 主线程等待子线程就绪
例如:主线程等待多个服务初始化完成后,再处理后续任务。 - 多线程任务拆分与汇总
例如:将大任务拆分为多个子任务,所有子任务完成后再合并结果。 - 并发测试
模拟高并发场景,让所有线程同时开始执行。
四、代码示例
java
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
int threadCount = 5;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
System.out.println("子线程执行任务...");
latch.countDown(); // 任务完成,计数器减1
}).start();
}
latch.await(); // 主线程等待所有子线程完成任务
System.out.println("所有子线程执行完毕,主线程继续!");
}
}
五、注意事项
- 计数器不可重置
若需重复使用,应选择CyclicBarrier
。 - 避免死锁
确保所有线程最终都会调用countDown()
,否则主线程无限阻塞。 - 性能优化
避免在高并发场景下频繁创建CountDownLatch
。 - 异常处理
在finally
块中调用countDown()
,防止线程异常导致计数未减少。
六、对比 CyclicBarrier
特性 | CountDownLatch |
CyclicBarrier |
---|---|---|
重用性 | 不可重置(一次性) | 可重复使用 |
核心角色 | 主线程等待子线程 | 子线程相互等待 |
触发条件 | 计数器归零 | 所有线程到达屏障点 |
总结 :
CountDownLatch
是轻量级线程协调工具,适用于"一等多"或"多等一"场景。通过计数器机制简化多线程协作,但需注意其不可重置的特性。