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

CyclicBarrier CountDownLatch

CyclicBarrierCountDownLatch 是 Java 并发包(java.util.concurrent)中的两个常用同步工具,它们用于协调多个线程的执行。然而,它们在设计和使用方式上有着显著的区别,特别是在可重复使用方面。

1. CyclicBarrier 是可重复使用的

CyclicBarrier 是一个循环的屏障(cyclic),其主要功能是让一组线程到达某个屏障点后再同时继续执行。当所有线程都到达屏障时,它会自动重置并进入下一轮等待,这就是它“可重复使用”的特性。它的重用性源于每次线程到达屏障后,会自动重置计数器,并允许再次使用。

  • 特点

    • 复用性:一旦所有线程都到达屏障并通过,屏障自动重置,允许这些线程或其他线程再次使用该屏障进行同步。这意味着 CyclicBarrier 可以在多个循环或阶段中重复使用。
    • 栅栏动作CyclicBarrier 还允许在线程到达屏障时执行一个栅栏动作(可选),该动作可以是某个特定的任务,如日志记录、数据汇总等。
  • 示例

    CyclicBarrier barrier = new CyclicBarrier(3); // 3个线程需要到达屏障Runnable task = () -> {try {System.out.println(Thread.currentThread().getName() + " 到达屏障");barrier.await();  // 等待其他线程到达屏障System.out.println(Thread.currentThread().getName() + " 通过屏障");} catch (Exception e) {e.printStackTrace();}
    };for (int i = 0; i < 3; i++) {new Thread(task).start();
    }// CyclicBarrier 可以重复使用,允许继续同步新的线程到达屏障
    // 运行结果
    Thread-2 到达屏障
    Thread-1 到达屏障
    Thread-0 到达屏障
    Thread-1 通过屏障
    Thread-2 通过屏障
    Thread-0 通过屏障
    

    这里,当所有 3 个线程都到达 barrier.await() 时,屏障将被释放,线程继续执行。在下一轮中,这些线程可以再次使用同一个 CyclicBarrier

2. CountDownLatch 是一次性的

CountDownLatch 是一个倒计时锁存器,它用于让一个或多个线程等待,直到其他线程完成某个操作。当计数器到达 0 时,所有等待的线程被释放,之后 CountDownLatch 就无法再次使用了。

  • 特点

    • 一次性使用CountDownLatch 是一次性的。一旦计数器从初始值倒数到 0,锁存器不能重置,也不能重新计数。如果需要再次使用,只能创建一个新的 CountDownLatch 实例。
    • 没有栅栏动作CountDownLatch 不像 CyclicBarrier 那样有一个统一的屏障动作,它只是一个简单的计数器,控制多个线程的同步。
  • 示例

    CountDownLatch latch = new CountDownLatch(3); // 初始计数为 3Runnable task = () -> {System.out.println(Thread.currentThread().getName() + " 完成任务");latch.countDown(); // 每个线程完成任务后调用 countDown()
    };for (int i = 0; i < 3; i++) {new Thread(task).start();
    }try {latch.await();  // 等待计数器变为 0System.out.println("所有任务完成,继续执行主线程");
    } catch (InterruptedException e) {e.printStackTrace();
    }// 运行结果:
    Thread-2 完成任务
    Thread-1 完成任务
    Thread-0 完成任务
    所有任务完成,继续执行主线程
    

    在这个例子中,CountDownLatch 初始计数为 3,表示需要 3 个线程完成任务。当计数器变为 0 时,主线程继续执行。然而,CountDownLatch 在计数变为 0 后无法重置,不能再次使用。

3. 为什么 CyclicBarrier 可重复使用,而 CountDownLatch 是一次性的?

  • 设计目的

    • CyclicBarrier:设计的目的是在循环或阶段性任务中使用,它允许同一批线程在不同的阶段都同步等待,完成一轮后可以自动重置并继续下一轮,因此它是循环使用的工具。
    • CountDownLatch:设计目的是让某个线程等待一组操作完成后继续执行,常用于一次性事件(如系统初始化、任务完成的信号)。它的计数一旦减为 0,表示操作已经完成,之后不能重新计数,因此是一次性的工具
  • 实现机制

    • CyclicBarrier:每当线程到达屏障并通过时,屏障自动重置,允许再次使用。其内部维护一个计数器和栅栏代(generation)来实现多次复用。
    • CountDownLatch:计数器一旦减到 0,锁存器就完成任务,无法重置,除非重新创建一个新的实例。

4. 使用场景的差异

  • CyclicBarrier 使用场景

    • 多线程分阶段处理任务时,每个阶段都需要所有线程在某个点上同步。例如,在一个并行算法中,多个线程需要在每个阶段结束时进行同步。
  • CountDownLatch 使用场景

    • 在某些初始化操作中,主线程需要等待其他线程完成后继续执行。例如,一个主线程等待几个工作线程完成任务,然后才继续执行。

总结

  • CyclicBarrier 可重复使用:它的设计允许在多个循环或阶段中重复使用,当一组线程到达屏障后,屏障会自动重置,进入下一轮等待。
  • CountDownLatch 是一次性的:它的计数器一旦到达 0,就无法再次使用,只能用于一次性任务协调。如果需要再次使用,必须创建新的实例。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • CSS 基础
  • 15.2 定义一个prometheus数据存储使用的pv
  • 若依Ruoyi之智能售货机运营管理系统(新增运营运维工单管理)
  • 第151天:红队APT-钓鱼篇邮件钓鱼SPF绕过自建邮件系统SwaksGophish
  • 如何让Google收录我的网站?
  • Docker 部署 Redis (图文并茂超详细)
  • 如何通俗易懂的解释TON的智能合约
  • HarmonyOS开发5.0【应用程序包】
  • webctf
  • 【机器学习-监督学习】集成学习与梯度提升决策树
  • 使用xml文件创建虚拟机
  • 【C++】容器
  • 数据结构与算法图论 并查集
  • 【c++】类和对象详解
  • 智能优化算法-鼠群优化算法(RSO)(附源码)
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 《Java编程思想》读书笔记-对象导论
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 30秒的PHP代码片段(1)数组 - Array
  • 77. Combinations
  • angular2 简述
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • js中的正则表达式入门
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • orm2 中文文档 3.1 模型属性
  • rabbitmq延迟消息示例
  • Zsh 开发指南(第十四篇 文件读写)
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • # 飞书APP集成平台-数字化落地
  • #AngularJS#$sce.trustAsResourceUrl
  • #NOIP 2014# day.1 T2 联合权值
  • (1)Nginx简介和安装教程
  • (4.10~4.16)
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (day 12)JavaScript学习笔记(数组3)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (二)JAVA使用POI操作excel
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (六)Hibernate的二级缓存
  • (论文阅读40-45)图像描述1
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (算法)硬币问题
  • (转)Sql Server 保留几位小数的两种做法
  • *算法训练(leetcode)第四十七天 | 并查集理论基础、107. 寻找存在的路径
  • .axf 转化 .bin文件 的方法
  • .NET C# 配置 Options