死磕并发之CountDownLatch解析

CountDownLatch解析

CountDownLatch是什么

CountDownLatch是基于AQS的阻塞工具,阻塞一个或者多个线程,直到所有的线程都执行完成。

CountDownLatch解决了什么问题

当一个任务运算量比较大的时候,需要拆分为各种子任务,必须要所有子任务完成后才能汇总为总任务。
使用并发模拟的时候可以使用CountDownLatch.也可以设置超时等待时间,

CountDownLatch 用法 1.阻塞所有线程执行完成后再执行 @Slf4j public class CountDownLatchExample { //线程数量 private static final int THREAD_NUM = 10; // CountdownLatch阻塞模拟 public static void main(String[] args) throws InterruptedException { // 创建线程池 用于执行线程 ExecutorService executorService = Executors.newCachedThreadPool(); //创建countDownLatch final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM); long startTime = System.currentTimeMillis(); //循环创建线程 for (int i = 0; i < THREAD_NUM; i++) { final int a = i; executorService.execute(() -> { try { test(a); } catch (Exception e) { log.error("Exception", e); } finally { countDownLatch.countDown(); } }); } countDownLatch.await(); long endTime = System.currentTimeMillis(); log.info("执行完毕,{}-{}",startTime,endTime); executorService.shutdown(); } private static void test(int num) throws InterruptedException { Thread.sleep(100); log.info("{}-{}", num,System.currentTimeMillis()); Thread.sleep(100); } }

结果
10:56:02.544 [pool-1-thread-5] INFO AQSExample.CountDownLatchExampleTimeOutTest - 4-1559271362542
10:56:02.543 [pool-1-thread-2] INFO AQSExample.CountDownLatchExampleTimeOutTest - 1-1559271362541
10:56:02.548 [pool-1-thread-10] INFO AQSExample.CountDownLatchExampleTimeOutTest - 9-1559271362548
10:56:02.544 [pool-1-thread-7] INFO AQSExample.CountDownLatchExampleTimeOutTest - 6-1559271362543
10:56:02.543 [pool-1-thread-4] INFO AQSExample.CountDownLatchExampleTimeOutTest - 3-1559271362542
10:56:02.544 [pool-1-thread-3] INFO AQSExample.CountDownLatchExampleTimeOutTest - 2-1559271362541
10:56:02.544 [pool-1-thread-8] INFO AQSExample.CountDownLatchExampleTimeOutTest - 7-1559271362543
10:56:02.544 [pool-1-thread-6] INFO AQSExample.CountDownLatchExampleTimeOutTest - 5-1559271362543
10:56:02.543 [pool-1-thread-1] INFO AQSExample.CountDownLatchExampleTimeOutTest - 0-1559271362541
10:56:02.548 [pool-1-thread-9] INFO AQSExample.CountDownLatchExampleTimeOutTest - 8-1559271362548
10:56:02.548 [main] INFO AQSExample.CountDownLatchExampleTimeOutTest - 执行完毕,1559271362441-1559271362548

上述结果可以看到,所有的线程执行完毕后主线程才打印出“执行完毕”。

死磕并发之CountDownLatch解析

2.按照超时时间阻塞所有线程执行,到时间后直接释放。

如果我们设置超时时间之后

@Slf4j public class CountDownLatchExampleTimeOutTest { //线程数量 private static final int THREAD_NUM = 10; // CountdownLatch阻塞模拟 public static void main(String[] args) throws InterruptedException { // 创建线程池 用于执行线程 ExecutorService executorService = Executors.newCachedThreadPool(); //创建countDownLatch final CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM); //循环创建线程 long startTime = System.currentTimeMillis(); for (int i = 0; i < THREAD_NUM; i++) { final int a = i; executorService.execute(() -> { try { test(a); } catch (Exception e) { log.error("Exception", e); } finally { countDownLatch.countDown(); } }); } countDownLatch.await(10,TimeUnit.MILLISECONDS); long endTime = System.currentTimeMillis(); log.info("执行完毕,{}-{}",startTime,endTime); executorService.shutdown(); } private static void test(int num) throws InterruptedException { Thread.sleep(50); log.info("{}-{}", num,System.currentTimeMillis()); } }

由于每个线程延迟50毫秒之后再执行,count已经超时了所以优先打印出了执行完毕的结果。然后在继续执行线程中的内容。

结果
11:14:55.509 [main] INFO AQSExample.CountDownLatchExampleTimeOutTest - 执行完毕,1559272495373-1559272495506
11:14:55.542 [pool-1-thread-1] INFO AQSExample.CountDownLatchExampleTimeOutTest - 0-1559272495542
11:14:55.542 [pool-1-thread-2] INFO AQSExample.CountDownLatchExampleTimeOutTest - 1-1559272495542
11:14:55.543 [pool-1-thread-3] INFO AQSExample.CountDownLatchExampleTimeOutTest - 2-1559272495543
11:14:55.543 [pool-1-thread-4] INFO AQSExample.CountDownLatchExampleTimeOutTest - 3-1559272495543
11:14:55.543 [pool-1-thread-5] INFO AQSExample.CountDownLatchExampleTimeOutTest - 4-1559272495543
11:14:55.544 [pool-1-thread-6] INFO AQSExample.CountDownLatchExampleTimeOutTest - 5-1559272495544
11:14:55.544 [pool-1-thread-7] INFO AQSExample.CountDownLatchExampleTimeOutTest - 6-1559272495544
11:14:55.545 [pool-1-thread-9] INFO AQSExample.CountDownLatchExampleTimeOutTest - 8-1559272495545
11:14:55.545 [pool-1-thread-8] INFO AQSExample.CountDownLatchExampleTimeOutTest - 7-1559272495545
11:14:55.545 [pool-1-thread-10] INFO AQSExample.CountDownLatchExampleTimeOutTest - 9-1559272495545

CountDownLatch源码解析

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyxgwf.html