CountDownLatch
是 Java 并发包 java.util.concurrent
中的一个类,它允许一个或多个线程等待其他线程完成操作。CountDownLatch
的工作原理是,它维护了一个计数器,这个计数器的初始值由构造函数设置。每当一个线程完成其任务后,计数器的值就会减一。当计数器的值减至零时,所有因调用 await()
方法而等待的线程都会被释放,继续执行。
以下是 CountDownLatch
的一些关键特性和应用场景:
关键特性
- 初始化计数器:在创建
CountDownLatch
对象时,需要指定一个初始的计数值。 - 等待(await):线程可以调用
await()
方法来等待计数器的值减至零。如果计数器的值不为零,调用await()
的线程会被阻塞,直到计数器的值变为零。 - 计数减一(countDown):每当一个任务完成时,可以调用
countDown()
方法来使计数器的值减一。
应用场景
- 并行计算的同步:当你有多个线程并行执行某项任务,并且需要等待所有线程都完成后才能继续执行后续操作时,可以使用
CountDownLatch
。 - 初始化资源的等待:在系统启动时,可能需要等待多个组件或资源初始化完成。使用
CountDownLatch
可以确保所有组件都准备好后再继续执行。 - 性能测试:在进行多线程性能测试时,可能需要同时启动多个线程来模拟并发请求,然后等待所有线程都执行完毕后再统计结果。
示例
下面是一个简单的示例,展示了如何使用 CountDownLatch
来等待多个线程完成:
import java.util.concurrent.CountDownLatch; | |
public class CountDownLatchExample { | |
public static void main(String[] args) throws InterruptedException { | |
int numTasks = 5; // 假设有5个任务需要并行执行 | |
CountDownLatch latch = new CountDownLatch(numTasks); // 初始化计数器为5 | |
for (int i = 0; i < numTasks; i++) { | |
new Thread(() -> { | |
System.out.println("任务开始执行..."); | |
// 模拟任务执行 | |
try { | |
Thread.sleep(1000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
System.out.println("任务执行完毕!"); | |
latch.countDown(); // 任务完成后,计数器减一 | |
}).start(); | |
} | |
latch.await(); // 等待所有任务完成 | |
System.out.println("所有任务都已完成!"); | |
} | |
} |
在这个示例中,我们创建了5个线程来模拟并行执行的任务。每个线程在执行完毕后都会调用 latch.countDown()
来使计数器的值减一。主线程调用 latch.await()
来等待所有任务完成。当所有任务都完成时,主线程会继续执行并输出 "所有任务都已完成!"。