记录CountDownLatch的一次简单使用

24 篇文章 3 订阅

最近这边连续下了好几天的雨了啊啊啊,你那边呢?
嗯哼?这开场的感觉不对呀,好尬,哈哈哈哈~
直接进入正题吧。

什么是CountDownLatch

这个是在JDK1.5开始就出现的,并发编程工具类。
这里偷懒下,直接看下源码上的类注释吧,相信你看完就差不多大概知道这个干啥子用的了。
在这里插入图片描述
在这里,请允许我用本人的蹩脚英文稍微翻译下:

可以允许一个或者多个线程等待,直到一组在其它线程里的操作都完成,然后再执行。
初始化CountDownLatch时提供一个count数,主方法一直将被阻塞直到多次调用CountDownLatch对象的countDown方法使得count数减至0为止。当所有等待的线程都被释放了,await后的一系列调用都立即返回(执行)。CountDownLatch只能执行一次这样的控制,如果你需要每个版本都重置下count数,可以考虑下CyclicBarrier。

怎么用呢

   public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(3);//计数器最初:3个任务
        MyWork work1 = new MyWork(countDownLatch, "1号");
        MyWork work2 = new MyWork(countDownLatch, "2号");
        MyWork work3 = new MyWork(countDownLatch, "3号");
        //固定大小线程池并行执行(每个任务都在不同的线程池里)
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(work1);
        executorService.submit(work2);
        executorService.submit(work3);
        //等待所有的任务完成
        countDownLatch.await();
        //所有任务完成,可以干其它的事情啦
        System.out.println("所有任务都完成啦");
    }

    static class MyWork implements Runnable {
        CountDownLatch countDownLatch;
        private String missionFlg;

        public MyWork(CountDownLatch countDownLatch, String missionFlg) {
            this.countDownLatch = countDownLatch;
            this.missionFlg = missionFlg;
        }

        @Override
        public void run() {
            try {
                //执行业务逻辑
                System.out.println(Thread.currentThread().getName() + "====> 执行任务" + missionFlg + "开始");
                Random random = new Random();
                //线程停留随机停留,表示任务的执行
                TimeUnit.SECONDS.sleep(random.nextInt(5));
                System.out.println(Thread.currentThread().getName() + "====> 执行任务" + missionFlg + "结束");
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "====> 执行任务" + missionFlg + "出现异常");
            } finally {
                //异常的状态下,也要记得发出信号,当前任务完成
                reduce();
            }
        }

        public void reduce() {
            //计数器减一
            countDownLatch.countDown();
        }
    }

执行结果:
在这里插入图片描述

自己使用过的场景

说一下自己一次的使用场景吧:

需求:产品给我一个表格,里面大概500多条下载链接,需要我临时写一个工具,快速地全部下载 并且要 生成一个下载结果(原链接和下载到磁盘的路径对照关系)。

实现:

  • 对任务列表进行拆分多个小的列表 list1,list2,list3 … listn;
  • 定义一个CountDownLatch对象,大小和上面的list的个数一致;
  • 启动 20 个线程池,把拆分后的列表依次丢到线程池;
  • 每个list的任务,都需要记录下每条记录的执行结果,存储到Redis 中;
  • 每个线程池每次执行完一个list 都 CountDownLatch里的计数器减一;
  • CountDownLatch#await 后写上生成 下载结果的 逻辑,这里就是从Redis 中读取执行结果列表,生成文件 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值