zoukankan      html  css  js  c++  java
  • Java并发包之CountDownLatch用法

    CountDownLatch计数器闭锁是一个能阻塞主线程,让其他线程满足特定条件下主线程再继续执行的线程同步工具。

    Latch闭锁的意思,是一种同步的工具类。类似于一扇门:在闭锁到达结束状态之前,这扇门一直是关闭着的,不允许任何线程通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。且当门打开了,就永远保持打开状态。

    CountDowmLatch是一种灵活的闭锁实现,包含一个计数器,该计算器初始化为一个正数,表示需要等待事件的数量。countDown方法递减计数器,表示有一个事件发生,而await方法等待计数器到达0,表示所有需要等待的事情都已经完成。

    这句话的意思是:在单独主线程的情况下,创建多个子线程, 在保证主线程同步的情况下,同时又让多个子线程处理,可以使用 CountDownLatch来阻塞主线程,等待子线程执行完成,主线程才执行后续操作.

    常见案例:

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

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

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

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

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

    注意事项:

    使用CountDownLatch必须确保计数器数量与子线程数量一致,且countDown必须要执行,否则出现计数器不为0,导致主线程一致等待的情况

    在执行任务的线程中,使用了try...finally结构,该结构可以保证创建的线程发生异常时CountDownLatch.countDown()方法也会执行,也就保证了主线程不会一直处于等待状态。

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

    具体代码示例:

    模拟乘客登机的场景

    package com.puppy.demo;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    //刘小品
    public class CountDownLatchTest {
    
        public static void main(String[] args) throws InterruptedException {
    
            System.out.println("南京禄口机场_机长正在等待所有乘客登机");
            //CountDownLatch的计数器数量必须与线程的数量一致,否则可能出现一直等待的情况,即计数器不为0的情况
            //使用CountDownLatch 需要注意,子线程中的countDown()最好放到finnally里面,防止计数器不为0
            CountDownLatch latch = new CountDownLatch(3);
    
            ExecutorService ex = Executors.newCachedThreadPool();
            ex.execute(new ThreadTest1(latch));
            ex.execute(new ThreadTest2(latch));
            ex.execute(new ThreadTest3(latch));
            //等待所有乘客来机场
            System.out.println("所有乘客都在赶飞机的路上");
    
            //latch.await(1,TimeUnit.SECONDS);//模拟超时等待的情况
            latch.await(); //模拟等待的情况,不考虑子线程的处理实际
            System.out.println("南京禄口机场_机长启动飞机起飞");
            ex.shutdown();
        }
    
    }
    
    class ThreadTest1 extends Thread {
    
        CountDownLatch lanch;
    
        public ThreadTest1() {
    
        }
    
        public ThreadTest1(CountDownLatch lanch) {
            this.lanch = lanch;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场");
            lanch.countDown();
        }
    }
    
    class ThreadTest2 extends Thread {
    
        CountDownLatch lanch;
    
        public ThreadTest2() {
    
        }
    
        public ThreadTest2(CountDownLatch lanch) {
            this.lanch = lanch;
        }
    
        @Override
        public void run() {
            System.out.println("正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场");
            lanch.countDown();
        }
    }
    
    class ThreadTest3 extends Thread {
        CountDownLatch lanch;
    
        public ThreadTest3() {
    
        }
    
        public ThreadTest3(CountDownLatch lanch) {
            this.lanch = lanch;
        }
    
        @Override
        public void run() {
            System.out.println("正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场");
            lanch.countDown();
        }
    }

    执行结果

    latch.await()

    南京禄口机场_机长正在等待所有乘客登机
    所有乘客都在赶飞机的路上
    正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场
    正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场
    正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场
    南京禄口机场_机长启动飞机起飞
    

     

    超时等待的情况:latch.await(1,TimeUnit.SECONDS)

    主线程已经执行完成,但是子线程才结束,latch.await(1,TimeUnit.SECONDS)方法

    南京禄口机场_机长正在等待所有乘客登机
    所有乘客都在赶飞机的路上
    正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场
    正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场
    南京禄口机场_机长启动飞机起飞
    正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场
    

      

    
    
  • 相关阅读:
    微信5.0绑定银行卡教程
    从陈坤微信号说起:微信公众平台开发者的江湖
    微信商业化解读
    微信公众平台开发(63)汽车查询
    微信公众平台开发(64)航班动态
    张小龙的微信帝国诞生记
    微信公众平台开发(65) 微博树洞
    微信公众平台开发(66)人品计算
    扫奖网-免费抽奖信息聚集平台
    微信公众平台开发(67)百度百科
  • 原文地址:https://www.cnblogs.com/lewisat/p/11057901.html
Copyright © 2011-2022 走看看