返回
CountDownLatch,让并发编程达成等待与同步之美
后端
2023-12-10 13:45:04
引子:裁判员等待所有运动员到来
想象一下,一场田径比赛即将开始,裁判员站在起跑线上,等待所有运动员全部到来后,才鸣枪发令。此时,裁判员扮演的角色与CountDownLatch在多线程编程中的作用十分相似。
CountDownLatch本质上是一个计数器,可以将一个线程阻塞,直到计数器减至0。与普通的计数器不同,CountDownLatch可以被多个线程同时操作,并提供线程安全保证。
CountDownLatch的工作原理
CountDownLatch的初始化需要传入一个整数参数,表示需要等待的任务数量。当某个线程调用countDown()方法时,计数器就会减1。当计数器减至0时,所有等待的线程都会被唤醒,继续执行。
CountDownLatch的使用场景
CountDownLatch适用于多种多线程编程场景,常见的有:
- 等待所有线程完成任务: 如上文提到的裁判员等待所有运动员到达的场景,可以用CountDownLatch来实现。
- 汇总多个线程的结果: 多个线程并行处理任务,当所有线程都完成后,汇总它们的结果。
- 控制并发线程数量: 限制并发线程的数量,防止系统资源过载。
CountDownLatch的代码示例
CountDownLatch的使用非常简单,以下是一个示例代码:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchExample {
public static void main(String[] args) {
// 创建一个CountDownLatch,初始值为5
CountDownLatch latch = new CountDownLatch(5);
// 创建一个线程池,并提交5个任务
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
executorService.submit(() -> {
// 模拟任务执行,随机休眠0-2秒
try {
Thread.sleep((long) (Math.random() * 2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
// 任务执行完成后,调用countDown()方法减少计数器
latch.countDown();
});
}
// 主线程等待所有任务完成
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 所有任务完成后,执行后续操作
System.out.println("所有任务完成,继续执行后续操作...");
// 关闭线程池
executorService.shutdown();
}
}
总结
CountDownLatch是一个非常有用的同步工具,它可以帮助多线程程序实现等待和同步。在本文中,我们介绍了CountDownLatch的工作原理、使用场景和代码示例。掌握CountDownLatch的用法,可以帮助您编写更可靠、更健壮的多线程程序。