CountDownLatch

1、并发流程控制

  倒数门闩

  例如:100米冲刺比赛,参赛者都准备好后,等裁判一声令下,全力冲出。

  流程:倒数结束之前,一直处于等待状态,直到倒计时结束了,此线程才继续工作。

2、类的主要方法介绍

  CountDownLatch(int count):仅有一个构造函数,参数 count 为需要倒数的数值。  

  await():调用 await() 方法的线程会被挂起,它会等待直到 count 值为 0 才继续执行。

  countDown():将 count 值减一,直到为 0 时,等待的线程会被唤起。

  

     初始化为 3 个计数器,Ta 等待倒计时,然后其他线程 T1、T2、T3 分别执行 countDown() ,到最后为 0 Ta 被唤醒,然后执行其他代码。

3、一等多

/**
 * @description 在工厂中,质检,5个人检查,所有人都认为通过,才通过
 * @author: hq
 * @create: 2022-08-20 14:54
 **/
public class CountDownLatchDemo1 {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            final int no = i + 1;
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep((long) (Math.random() * 10000L));
                        System.out.println("No." + no + "完成工作");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        countDownLatch.countDown();
                    }
                }
            };
            executorService.execute(runnable);
        }
        System.out.println("等待5人检查完。。。");
        countDownLatch.await();
        System.out.println("所有人都完成工作");
    }
}

  

 4、多等一

/**
 * @description 模拟100米跑步,5名选手都准备好了,就等裁判员法令。同时跑出
 * @author: hq
 * @create: 2022-08-20 15:05
 **/
public class CountDownLatchDemo2 {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch begin = new CountDownLatch(1);
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            final int no = i + 1;
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("No." + no + "准备完毕,等待发令");
                    try {
                        begin.await();
                        System.out.println("No." + no + "开始跑步");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            executorService.execute(runnable);
        }
        Thread.sleep(5000);
        System.out.println("发令,比赛开始");
        begin.countDown();
    }

}

  

 5、将一等多,多等一结合在一起

/**
 * @description
 * @author: hq
 * @create: 2022-08-20 15:12
 **/
public class CountDownLatchDemo3 {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch end = new CountDownLatch(5);
        CountDownLatch begin = new CountDownLatch(1);
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            final int no = i + 1;
            executorService.execute(() -> {
                System.out.println("No." + no + "准备好了");
                try {
                    begin.await();
                    // 一声令下,开始比赛
                    Thread.sleep((long) (Math.random() * 10000));
                    System.out.println("No." + no + "冲过终点");
                    end.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        //裁判检查情况
        Thread.sleep(2000);
        // 一声令下
        begin.countDown();
        System.out.println("一声令下,比赛开始");
        end.await();
        System.out.println("所有人冲过终点,比赛结束");
    }
}

6、 注意点

  CountDownLatch 不能回滚重置,重复使用。

 

posted @ 2022-08-20 15:45  放手解脱  阅读(83)  评论(0编辑  收藏  举报