Java多线程CountDownLatch的实现

介绍

CountDownLatch是一个同步辅助类,它允许一个或多个线程一直等待直到其他线程执行完毕才开始执行。

用给定的计数初始化CountDownLatch,其含义是要被等待执行完的线程个数。

每次调用CountDown(),计数减1

主程序执行到await()函数会阻塞等待线程的执行,直到计数为0

场景

1:多线程读取批量文件, 并且读取完成之后汇总处理

2:多线程读取Excel多个sheet,读取完成之后获取汇总获取的结果

3:多个人一起一起来吃饭,主人等待客人到来,客人一个个从不同地方来到饭店,主人需要等到所有人都到来之后,才能开饭

4:汽车站,所有乘客都从不同的地方赶到汽车站,必须等到所有乘客都到了,汽车才会出发,(如果设置了超时等待,那么当某个时间点到了,汽车也出发)

5: 百米赛跑,4名运动员选手到达场地等待裁判口令,裁判一声口令,选手听到后同时起跑,当所有选手到达终点,裁判进行汇总排名

6: 4名选手进行大众投票,投票现场有500个票, 投票时间是30分钟,500个票投完结束投票,或者投票时间到了也结束投票

作用:可以用来确保某些活动直到其他活动都完成后才继续执行。

CountDownLatch非常适合于对任务进行拆分,使其并行执行,比如某个任务执行2s,其对数据的请求可以分为五个部分,那么就可以将这个任务拆分为5个子任务,分别交由五个线程执行,执行完成之后再由主线程进行汇总,此时,总的执行时间将决定于执行最慢的任务,平均来看,还是大大减少了总的执行时间。

注意事项:

  • 使用CountDownLatch必须确保计数器数量与子线程数量一致,且countDown必须要执行,否则出现计数器不为0,导致主线程一致等待的情况
  • 在执行任务的线程中,使用了try...finally结构,该结构可以保证创建的线程发生异常时CountDownLatch.countDown()方法也会执行,也就保证了主线程不会一直处于等待状态。

案例(模拟乘客登机的场景)

    public static void main(String[] args) {
        CountDownLatchUtils.initialize("da1", 5);
        List<String> list=new CopyOnWriteArrayList<>();

        ExecutorUtils.create(()->{
            System.out.println("张三正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场");
            SleepTools.second(4);
            list.add("张三");
            CountDownLatchUtils.countDown("da1");
        });
        ExecutorUtils.create(()->{
            System.out.println("李四正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场");
            SleepTools.second(15);
            list.add("李四");
            CountDownLatchUtils.countDown("da1");
        });

        ExecutorUtils.create(()->{
            System.out.println("王五正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场");
            SleepTools.second(9);
            list.add("王五");
            CountDownLatchUtils.countDown("da1");
        });

        ExecutorUtils.create(()->{
            //飞机起飞
            CountDownLatchUtils.await("da1",10);  //这里先模拟10秒 360秒=1小时
            System.out.println("南京禄口机场_机长启动飞机起飞");
            //当前航班已到乘客
            System.out.println("当前航班已到乘客"+list);
        });
    }

以上代码都是我封装后的,主要是看逻辑就行了

张三正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场
李四正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场
王五正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场
南京禄口机场_机长启动飞机起飞
当前航班已到乘客[张三, 王五]

到此这篇关于Java多线程CountDownLatch的实现的文章就介绍到这了,更多相关Java多线程CountDownLatch内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java中多线程同步类 CountDownLatch

    在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法: CountDownLatch(int count) 参数count是计数器,一般用要执行线程的数量来赋值. long getCount():获得当前计数器的值. void countDown():当计数器的值大于零时,调用方法,计数器的数值减少1,当计数器等数零时,释放所有的线程. void await():调所该方法阻塞当前主线程,直到计数器减

  • Java多线程编程之CountDownLatch同步工具使用实例

    好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行. java.util.concurrent.CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数初始化CountDownLatch.由于调用了countDown()方法,所以在当前计数到达零之前,await方法会一直受阻塞.之后,会释放所有等待的线程,await的所有后续调用都将立即返回.这种现

  • 如何使用CountDownLatch同步java多线程

    最近写了一个并发幂等测试,用线程池加入多个线程,同时启动,领导觉得这样有一定的风险,要求更严格一点,把所有的线程加入池中,然后同时启动. 本来有多种方法,因为我们需要从多个线程中获取返回值,所以我们用CountDownLatch来同步多线程.CyclicBarrier也是可以同步多线程的,但因为其无法获取返回值,最后只能选择CountDownLatch. 因公司的代码不便共享,这里只提供一小部分代码. CountDownLatch latch = new CountDownLatch(1); <

  • Java多线程之同步工具类CountDownLatch

    前言: CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行.例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有框架服务之后执行. 1 CountDownLatch主要方法 void await():如果当前count大于0,当前线程将会wait,直到count等于0或者中断. PS:当count等于0的时候,再去调用await() , 线程将不会阻塞,而是立即运行.后面可以通过源码分析得到. boolean await(long t

  • Java countDownLatch如何实现多线程任务阻塞等待

    我这里需要通过多线程去处理数据,然后在所有数据都处理完成后再往下执行.这里就用到了CountDownLatch.把countdownlatch作为参数传入到每个线程类里,在线程中处理完数据后执行countdown方法.在所有countdownlatch归零后,其await方法结束阻塞状态而往下执行. 具体代码如下: 将多线程任务提交线程池 @Bean(name = "ggnews_executor") public Executor postExecutor() { ThreadPoo

  • JAVA多线程CountDownLatch使用详解

    前序: 上周测试给开发的同事所开发的模块提出了一个bug,并且还是偶现. 经过仔细查看代码,发现是在业务中启用了多线程,2个线程同时跑,但是新启动的2个线程必须保证一个完成之后另一个再继续运行,才能消除bug. 什么时候用? 多线程是在很多地方都会用到的,但是我们如果想要实现在某个特定的线程运行完之后,再启动另外一个线程呢,这个时候CountDownLatch就可以派上用场了 怎么用? 先看看普通的多线程代码: package code; public class MyThread extend

  • Java多线程CountDownLatch的实现

    介绍 CountDownLatch是一个同步辅助类,它允许一个或多个线程一直等待直到其他线程执行完毕才开始执行. 用给定的计数初始化CountDownLatch,其含义是要被等待执行完的线程个数. 每次调用CountDown(),计数减1 主程序执行到await()函数会阻塞等待线程的执行,直到计数为0 场景 1:多线程读取批量文件, 并且读取完成之后汇总处理 2:多线程读取Excel多个sheet,读取完成之后获取汇总获取的结果 3:多个人一起一起来吃饭,主人等待客人到来,客人一个个从不同地方

  • java多线程CountDownLatch与线程池ThreadPoolExecutor/ExecutorService案例

    1.CountDownLatch: 一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行. 2.ThreadPoolExecutor/ExecutorService: 线程池,使用线程池可以复用线程,降低频繁创建线程造成的性能消耗,同时对线程的创建.启动.停止.销毁等操作更简便. 3.使用场景举例: 年末公司组织团建,要求每一位员工周六上午8点到公司门口集合,统一乘坐公司所租大巴前往目的地. 在这个案例中,公司作为主线程,员工作为子线程. 4.代码示例: package

  • java多线程CyclicBarrier的使用案例,让线程起步走

    1.CyclicBarrier: 一个同步辅助类,用于协调多个子线程,让多个子线程在这个屏障前等待,直到所有子线程都到达了这个屏障时,再一起继续执行后面的动作. 2.使用场景举例: 年末公司组织团建,要求每一位员工周六上午8点[自驾车]到公司门口集合,然后[自驾车]前往目的地. 在这个案例中,公司作为主线程,员工作为子线程. 3.代码示例: package com.test.spring.support; import java.util.concurrent.BrokenBarrierExce

  • Java中CountDownLatch进行多线程同步详解及实例代码

    Java中CountDownLatch进行多线程同步详解 CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantLock.ReadWriteLock锁实现同步. 3.信号量Semaphore实现同步. 其中,synchronized关键字和Lock锁解决的是多个线程对同一资源的并发访问问题.信号量Semaphore解决的是多副本资源的共享访问问题. 今天

  • java多线程之并发工具类CountDownLatch,CyclicBarrier和Semaphore

    目录 CountDownLatch Semaphore CyclicBarrier 总结 CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成操作. 假设一个Excel文件有多个sheet,我们需要去记录每个sheet有多少行数据, 这时我们就可以使用CountDownLatch实现主线程等待所有sheet线程完成sheet的解析操作后,再继续执行自己的任务. public class CountDownLatchTest { private static

  • Java多线程同步工具类CountDownLatch详解

    目录 简介 核心方法 CountDownLatch如何使用 CountDownLatch运行流程 运用场景 总结 简介 CountDownLatch是一个多线程同步工具类,在多线程环境中它允许多个线程处于等待状态,直到前面的线程执行结束.从类名上看CountDown既是数量递减的意思,我们可以把它理解为计数器. 核心方法 countDown():计数器递减方法. await():使调用此方法的线程进入等待状态,直到计数器计数为0时主线程才会被唤醒. await(long, TimeUnit):在

  • 分享40个Java多线程问题小结

    Java多线程是什么 Java提供的并发(同时.独立)处理多个任务的机制.多个线程共存于同一JVM进程里面,所以共用相同的内存空间,较之多进程,多线程之间的通信更轻量级.依我的理解,Java多线程完全就是为了提高CPU的利用率.Java的线程有4种状态,新建(New).运行(Runnable).阻塞(Blocked).结束(Dead),关键就在于阻塞(Blocked),阻塞意味着等待,阻塞的的线程不参与线程分派器(Thread Scheduler)的时间片分配,自然也就不会使用到CPU.多线程环

  • Java多线程的调度_动力节点Java学院整理

    有多个线程,如何控制它们执行的先后次序?         方法一:设置线程优先级. java.lang.Thread 提供了 setPriority(int newPriority) 方法来设置线程的优先级,但线程的优先级是无法保障线程的执行次序的,优先级只是提高了优先级高的线程获取 CPU 资源的概率.也就是说,这个方法不靠谱.       方法二:使用线程合并. 使用 java.lang.Thread 的 join() 方法.比如有线程 a,现在当前线程想等待 a 执行完之后再往下执行,那就

随机推荐