CountDownLatch
是 Java java.util.concurrent
包中的一个同步辅助类,用于协调多个线程之间的同步。它允许一个或多个线程等待直到一组操作完成。
主要特点
CountDownLatch
是一个计数器,初始化时设置一个正整数,表示需要等待的事件数。- 调用
countDown()
方法会使计数器减一,当计数器的值变为零时,所有在await()
方法上等待的线程将被唤醒。 - 一旦计数器达到零,
CountDownLatch
无法重置。
使用场景
CountDownLatch
常用于以下场景:
- 在主线程中启动多个工作线程并等待所有线程完成工作。
- 实现某种类型的延迟启动,只有在某个事件发生后才开始执行(例如等待多个服务启动)。
- 等待多个线程完成某个操作后再执行后续操作。
使用示例
以下是一个 CountDownLatch
的基本用法示例:
import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) {// 创建一个 CountDownLatch,初始计数为3CountDownLatch latch = new CountDownLatch(3);// 创建并启动3个线程for (int i = 0; i < 3; i++) {new Thread(new Worker(latch)).start();}try {// 主线程等待latch.await();} catch (InterruptedException e) {e.printStackTrace();}// 所有线程完成后执行System.out.println("所有线程已完成,主线程继续执行。");}
}class Worker implements Runnable {private CountDownLatch latch;public Worker(CountDownLatch latch) {this.latch = latch;}@Overridepublic void run() {try {// 模拟工作Thread.sleep((long) (Math.random() * 1000));System.out.println(Thread.currentThread().getName() + " 完成工作。");} catch (InterruptedException e) {e.printStackTrace();} finally {// 每个线程完成工作后计数减1latch.countDown();}}
}
代码分析
- 初始化:创建
CountDownLatch
的实例并设定初始计数为 3。 - 启动线程:启动 3 个工作线程,每个线程在完成工作后调用
latch.countDown()
,使计数器减一。 - 主线程等待:主线程调用
latch.await()
,在此处等待,直到CountDownLatch
的计数器为 0。 - 计数器归零:一旦所有线程调用了
countDown()
,计数器达到零,主线程将继续执行。
注意事项
CountDownLatch
的计数器一旦为零,就不能重置。如果需要重新开始,请考虑使用CyclicBarrier
或其他机制。- 如果在调用
await()
的地方线程被中断,将会抛出InterruptedException
,通常需要处理该异常。 CountDownLatch
适合用于等待多个线程的完成,而不是用于在多次执行中动态增加或减少计数的场景。
通过合理使用 CountDownLatch
,可以有效地协调多线程之间的执行,让程序在处理并发任务时更加高效和可靠。