当前位置: 首页 > news >正文

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

http://www.mrgr.cn/news/62265.html

相关文章:

  • 咖啡基础知识与扫盲
  • vue3项目中引入阿里图标库
  • WPF数据绑定的五大模式
  • Kubernetes:(四)kubectl命令
  • Django ORM 数据库管理 提高查询、更新性能的技巧和编程习惯:
  • 【面试经典150】day 9
  • 头歌网络安全爬虫
  • Redis 发布订阅 总结
  • 图像篡改研究
  • 未来生活中的AI电脑是怎样的
  • 【Python单元测试】pytest框架单元测试常用用例
  • Go性能基础
  • 【股东权益与市值:概念、计算与差异分析】
  • 关于防止布局底部有弹簧而导致的QWidget闪烁问题
  • 12-Docker发布微服务
  • STM32的隐藏定时器---DWT
  • 为什么大模型都是Decoder-only结构?
  • Python入门——iter迭代器—__iter__()方法__next__()方法
  • 详解RabbitMQ三种队列类型
  • Rust编程中的浮点数比较
  • 多线程显示 CSV 2 PNG 倒计时循环播放
  • Redis 淘汰策略 问题
  • leetcode hot100【LeetCode 230. 二叉搜索树中第K小的元素】java实现
  • DOM---鼠标事件类型(移入移出)
  • Java AQS Semaphore 源码
  • 天润融通突破AI客服局限,三大关键提升文本机器人问答效果