CountDownLatch与CyclicBarrier的比较&应用

CountDownLatch与CyclicBarrier的比较&应用

CountDownLatch

说明

一个线程等待其他线程执行完之后再执行,相当于加强版的join,在初始化CountDownLatch是需要设定计数器的数值(计数器数据不一定跟线程数相同,但是一定计数器的值一定是要大于等于线程数,一个线程中可以进行多次扣减。当计数器扣减至0时才可继续向下执行

示例代码

@Slf4j
public class TestCountDownLatch {
    public static CountDownLatch countDownLatch = new CountDownLatch(5);

    public static void main(String[] args) throws InterruptedException {

        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < 5; i++) {
            executorService.execute(TestCountDownLatch::doTasK);
        }
        countDownLatch.await();
        log.info("所有线程执行完毕,开始执行主线程");
    }

    private static void doTasK() {
        try {
            log.info("线程{}开始准备", Thread.currentThread().getName());
            Thread.sleep(RandomUtil.randomLong(1000, 3000));
            countDownLatch.countDown();
            log.info("线程{}准备完毕", Thread.currentThread().getName());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
结果
21:44:07.747 [pool-1-thread-1] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-1开始准备
21:44:07.747 [pool-1-thread-5] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-5开始准备
21:44:07.747 [pool-1-thread-2] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-2开始准备
21:44:07.747 [pool-1-thread-3] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-3开始准备
21:44:07.747 [pool-1-thread-4] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-4开始准备
21:44:08.878 [pool-1-thread-4] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-4准备完毕
21:44:08.887 [pool-1-thread-1] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-1准备完毕
21:44:09.464 [pool-1-thread-3] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-3准备完毕
21:44:10.017 [pool-1-thread-5] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-5准备完毕
21:44:10.633 [pool-1-thread-2] INFO com.huakai.springenv.juc.TestCountDownLatch - 线程pool-1-thread-2准备完毕
21:44:10.633 [main] INFO com.huakai.springenv.juc.TestCountDownLatch - 所有线程执行完毕,开始执行主线程

应用场景

  1. 一个操作依赖多个前置操作的完成(为了提高效率,前置操作使用多线程执行)才能开始执行
    • 比如计算用户任务的完成情况,任务的完成情况依赖于不同需要外部接口,这里执行多线程执行外部接口的调用,等待所所有调用完成后开始计算用户的任务完成情况

Cyclicbarrier

说明

让一组线程到达某个屏障,然后被阻塞,一直到最后一个线程到达屏障,然后所有屏障开放,所有被阻塞的线程继续执行,计数器与线程数相等。

示例代码

@Slf4j
public class TestCycleBarrier {
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,()->log.info("所有线程已经准备完毕"));

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < 5; i++) {
            executorService.execute(TestCycleBarrier::doTasK);
        }
    }

    private static void doTasK() {
        try {
            log.info("线程{}开始准备",Thread.currentThread().getName());
            Thread.sleep(RandomUtil.randomLong(1000,3000));
            cyclicBarrier.await();
            log.info("线程{}开始执行",Thread.currentThread().getName());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
结果
21:47:05.762 [pool-1-thread-1] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-1开始准备
21:47:05.762 [pool-1-thread-2] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-2开始准备
21:47:05.762 [pool-1-thread-4] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-4开始准备
21:47:05.762 [pool-1-thread-5] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-5开始准备
21:47:05.762 [pool-1-thread-3] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-3开始准备
21:47:08.383 [pool-1-thread-3] INFO com.huakai.springenv.juc.TestCycleBarrier - 所有线程已经准备完毕
21:47:08.383 [pool-1-thread-1] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-1开始执行
21:47:08.383 [pool-1-thread-5] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-5开始执行
21:47:08.383 [pool-1-thread-4] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-4开始执行
21:47:08.383 [pool-1-thread-2] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-2开始执行
21:47:08.383 [pool-1-thread-3] INFO com.huakai.springenv.juc.TestCycleBarrier - 线程pool-1-thread-3开始执行

应用场景

  1. 一组操作需要分为多步(为了提高效率,每一步的任务都拆成了子任务并行执行)完成,每一步操作必须等待所有的上一步操作的完成
    • 在数据分析的流程中,分为数据清洗和数据分析,数据因为量比较大,清洗和分析都分为了多个任务执行,但在执行任务分析之前,必须保证所有的数据都完成清洗
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值