CountDownLatch 和 CyclicBarrier的区别与详解

一、概念说明

CountDownLatch通过一个计数器来实现,计数器的初始化值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就相应的减1。当计数器到达0时,表示所有的线程都已完成任务,然后在CountDownLatch上等待的线程就可以恢复执行任务。

CyclicBarrier是一个同步辅助工具,它允许一组线程互相等待,直到所有线程都到达某个公共屏障点(barrier point),然后才能继续执行。CyclicBarrier在初始化时需要设定一个线程数量,当线程数量达到这个数量时,所有在CyclicBarrier上等待的线程才会继续执行。CyclicBarrier是一个可重复使用的屏障,也就是说,当所有线程都到达屏障点后,CyclicBarrier会被重置,以便再次使用。

             

二、异同点

CountDownLatch和CyclicBarrier的相同点是:都可以实现线程间的等待

  1. 侧重点不同:CountDownLatch一般用于一个线程等待一组其它线程;而CyclicBarrier一般是一组线程间的相互等待至某同步点。
  1. 重用性不同:CountDownLatch在倒数到0并且触发门闩打开后,就不能再次使用了,除非新建一个新的实例;而CyclicBarrier的计数器是可以重用的。

三、代码示例

countDownLatch

static CountDownLatch countDownLatch = new CountDownLatch(2);

private static void countDownLatch() {
        System.out.println("全班同学开始考试:一共两个学生");
        new Thread(() -> {
            try {
                Thread.sleep(2000);
                ThreadUtil.safeSleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("第一个同学交试卷");
            countDownLatch.countDown();
        }).start();

        new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("第二个同学交试卷");
            countDownLatch.countDown();
        }).start();

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("老师收齐试卷离开考场");
    }

  

cycliBarrier

 private static void cycliBarrier() {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
            System.out.println("汇总1 ...");

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("汇总2 ...");
        });
        for(int i = 0;i < 3;i ++) {
            new Thread(() -> {
                try {
                    Thread.sleep((long)(Math.random() * 2000));

                    int randomInt = new Random().nextInt(500);
                    System.out.println("你 " + randomInt);

                    cyclicBarrier.await();

                    System.out.println("好 " + randomInt);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

  

cycliBarrier构造方式Runnable可选,执行的时机都是所有的线程到达屏障后执行Runnable的方法然后各自继续向下执行。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值