Java中CountDownLatch和CyclicBarrier的区别与详解
一.CountDownLatch 和 CyclicBarrier的区别
CountDownLatch 的计数器是大于或等于线程数的,而CyclicBarrier是一定等于线程数CountDownLatch 放行由其他线程控制而CyclicBarrier是由本身来控制的
二.详解
CountDownLatch
说明: 一个线程等待其他线程执行完之后再执行,相当于加强版的join,在初始化CountDownLatch是需要设定计数器的数值(计数器数据不一定跟线程数相同,但是一定计数器的值一定是要大于等于线程数,一个线程中可以进行多次扣减。当计数器扣减至0时才可继续向下执行)
举例说明:
比如LOL在游戏开始时需要玩家全部准备完毕之后才开始,开始游戏可以理解为“主线程”,玩家准备理解为“其他线程”,在“其他线程”没有准备完毕之前,“主线程时等待状态”,当“其他线程”准备完毕之后“主线程”就会执行下一步开始游戏的动作
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public class CountDownLatchTest { private static CountDownLatch countDownLatsh = new CountDownLatch( 5 ); private static class Player implements Runnable{ private Integer index; public Player(Integer index){ this .index = index; } @Override public void run() { System.out.println( "玩家" +index+ "准备完成" ); countDownLatsh.countDown(); } } public static void main(String[] args) throws InterruptedException { for ( int i = 0 ; i < 5 ; i++){ Player player = new Player(i); Thread thread = new Thread(player); thread.start(); } countDownLatsh.await(); System.out.println( "玩家准备完毕,开始游戏" ); } } |
运行结果
玩家0准备完成
玩家1准备完成
玩家2准备完成
玩家3准备完成
玩家4准备完成
玩家准备完毕,开始游戏
cyclicbarrier
说明: 让一组线程到达某个屏障,然后被阻塞,一直到最后一个线程到达屏障,然后屏障开放,所有被阻塞的线程继续执行,计数器与线程数相等。
CyclicBarrier(int parties, Runnable barrierAction) 当时使用这个构造函数时,barrierAction定义的任务会执行
举例说明: 假设有一家公司要全体员工进行团建活动,活动内容为翻越三个障碍物,每一个人翻越障碍物所用的时间是不一样的。但是公司要求所有人在翻越当前障碍物之后再开始翻越下一个障碍物,也就是所有人翻越第一个障碍物之后,才开始翻越第二个,以此类推比如跨栏比赛,我们修改一下规则,当所有选手都跨过第一个栏杆是,才去跨第二个,以此类推,每一个员工都是一个“其他线程”。当所有人都翻越的所有的障碍物之后,程序才结束。而主线程可能早就结束了,这里我们不用管主线程。
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public class CyclicBarrierTest { private static CyclicBarrier cyclicBarrier = new CyclicBarrier( 5 ); public static class Surmount implements Runnable{ @Override public void run() { try { for ( int i = 1 ; i < 4 ; i++){ Random rand = new Random(); int randomNum = rand.nextInt(( 3000 - 1000 ) + 1 ) + 1000 ; //产生1000到3000之间的随机整数 Thread.sleep(randomNum); String name = Thread.currentThread().getName(); System.out.println(name+ "翻过了第" + i + "个障碍" ); cyclicBarrier.await(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } public static void main(String[] args){ for ( int i = 1 ; i < 6 ; i++){ Thread thread = new Thread( new Surmount(), "选手" + i ); thread.start(); } System.out.println( "main is end" ); } } |
运行结果:
main is end
选手4翻过了第1个障碍
选手2翻过了第1个障碍
选手1翻过了第1个障碍
选手5翻过了第1个障碍
选手3翻过了第1个障碍
选手1翻过了第2个障碍
选手4翻过了第2个障碍
选手3翻过了第2个障碍
选手5翻过了第2个障碍
选手2翻过了第2个障碍
选手5翻过了第3个障碍
选手2翻过了第3个障碍
选手1翻过了第3个障碍
选手4翻过了第3个障碍
选手3翻过了第3个障碍
到此这篇关于Java中CountDownLatch和CyclicBarrier的区别与详解的文章就介绍到这了,更多相关Java CountDownLatch CyclicBarrier内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2019-09-25 js 操作数组