一.CountDownLatch介绍
CountDownLatch是一个并发工具类, 作用是允许一个或多个线程等待其他线程完成操作。我们有时会称之为发令枪。有一个个形象的例子能说明其功能:公司召开一个全体股东会,需要所有股东到场了才能正式开始。会议室准备了一个花名册,记录了需要到会的总人数,每一个股东来到会议室就要签名确认,同时总人数减一,当需要到会的总人数为0时,会议就正式开始。所以,CountDownLatch就有充当计数器和发令枪的功能。
二.结合ExecutorService实现拆分任务并发执行
一般我们业务场景中经常会有执行一个大任务,如果我们串行执行,则效率较慢。我们应用分而治之的思想,将其拆分,启动多个线程来并行。但是如果目前不阻塞主线程,可能在子线程进行中的过程中,主线程已结束。这样也无法最终汇总结果了。此时引入CountDownLatch便能解决这个痛点。
//利用countDownLatch结合ExecutorService在并发执行任务时,能够保证子线程任务结束后,主线程才继续往下走。
CountDownLatch countDownLatch = new CountDownLatch(3);
ExecutorService executorService = Executors.newFixedThreadPool(3);
Runnable runnable1 = () -> {
System.out.println(111111);
countDownLatch.countDown();
};
Runnable runnable2 = () -> {
System.out.println(222222);
countDownLatch.countDown();
};
Runnable runnable3 = () -> {
System.out.println(333333);
countDownLatch.countDown();
};
executorService.execute(runnable1);
executorService.execute(runnable2);
executorService.execute(runnable3);
//阻塞当前主线程
countDownLatch.await();
System.out.println("主线程结束返回结果");
任务拆分为几个线程来执行,则CountDownLatch就是多少。
当子线程都执行完毕了,此时CountDownLatch为0,主线程不再阻塞,继续往下走。
三.模拟高并发
有时我们写测试用例时,想要模拟一些并发场景,这时可以引入CountDownLatch。
private static final int MAX_THREAD = 10000;
private CountDownLatch cdl = new CountDownLatch(MAX_THREAD);
@Test
public void countDownLatchTest() throws InterruptedException {
//模拟并发
for (int i =0;i<MAX_THREAD;i++){
Thread thread = new Thread(() -> {
cdl.countDown();
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
//测试调用业务接口等
System.out.println(new Date());
});
thread.start();
}
Thread.sleep(2000);
}
如上便是模拟10000的并发,主线程肯定要sleep下,不然直接就结束了,子线程的结果也会来不及打印出来。
本文深入讲解CountDownLatch在并发编程中的应用,包括作为并发任务协调工具,确保主线程等待子线程完成;以及如何使用它结合ExecutorService实现任务的拆分与并发执行,提升效率;最后演示了如何利用CountDownLatch模拟高并发场景,进行并发测试。

1339

被折叠的 条评论
为什么被折叠?



