CountDownLatch和CyclicBarrier的功能看起来很相似,不易区分,有一种谜之的神秘。本文将通过通俗的例子并结合代码讲解两者的使用方法和区别。

CountDownLatch和CyclicBarrier都是java.util.concurrent包下面的多线程工具类。

从字面上理解,CountDown表示减法计数,Latch表示门闩的意思,计数为0的时候就可以打开门闩了。Cyclic Barrier表示循环的障碍物。两个类都含有这一个意思:对应的线程都完成工作之后再进行下一步动作,也就是大家都准备好之后再进行下一步。然而两者最大的区别是,进行下一步动作的动作实施者是不一样的。这里的“动作实施者”有两种,一种是主线程(即执行main函数),另一种是执行任务的其他线程,后面叫这种线程为“其他线程”,区分于主线程。对于CountDownLatch,当计数为0的时候,下一步的动作实施者是main函数;对于CyclicBarrier,下一步动作实施者是“其他线程”。

下面举例说明:

对于CountDownLatch,其他线程为游戏玩家,比如英雄联盟,主线程为控制游戏开始的线程。在所有的玩家都准备好之前,主线程是处于等待状态的,也就是游戏不能开始。当所有的玩家准备好之后,下一步的动作实施者为主线程,即开始游戏。

我们使用代码模拟这个过程,我们模拟了三个玩家,在三个玩家都准备好之后,游戏才能开始。代码的输出结果为:

  1. 正在等待所有玩家准备好
  2. player0 已经准备好了, 所使用的时间为 1.235s
  3. player2 已经准备好了, 所使用的时间为 1.279s
  4. player3 已经准备好了, 所使用的时间为 1.358s
  5. player1 已经准备好了, 所使用的时间为 2.583s
  6. 开始游戏

CountDownLatch的代码:

  1. import java.util.Random;
  2. import java.util.concurrent.CountDownLatch;
  3. public class CountDownLatchTest {
  4. public static void main(String[] args) throws InterruptedException {
  5. CountDownLatch latch = new CountDownLatch(4);
  6. for(int i = 0; i < latch.getCount(); i++){
  7. new Thread(new MyThread(latch), "player"+i).start();
  8. }
  9. System.out.println("正在等待所有玩家准备好");
  10. latch.await();
  11. System.out.println("开始游戏");
  12. }
  13. private static class MyThread implements Runnable{
  14. private CountDownLatch latch ;
  15. public MyThread(CountDownLatch latch){
  16. this.latch = latch;
  17. }
  18. @Override
  19. public void run() {
  20. try {
  21. Random rand = new Random();
  22. int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数
  23. Thread.sleep(randomNum);
  24. System.out.println(Thread.currentThread().getName()+" 已经准备好了, 所使用的时间为 "+((double)randomNum/1000)+"s");
  25. latch.countDown();
  26. } catch (InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }
  31. }

对于CyclicBarrier,假设有一家公司要全体员工进行团建活动,活动内容为翻越三个障碍物,每一个人翻越障碍物所用的时间是不一样的。但是公司要求所有人在翻越当前障碍物之后再开始翻越下一个障碍物,也就是所有人翻越第一个障碍物之后,才开始翻越第二个,以此类推。类比地,每一个员工都是一个“其他线程”。当所有人都翻越的所有的障碍物之后,程序才结束。而主线程可能早就结束了,这里我们不用管主线程。

我们使用代码来模拟上面的过程。我们设置了三个员工和三个障碍物。可以看到所有的员工翻越了第一个障碍物之后才开始翻越第二个的,下面是运行结果:


  1. main function is finished.
  2. 队友1, 通过了第0个障碍物, 使用了 1.432s
  3. 队友0, 通过了第0个障碍物, 使用了 1.465s
  4. 队友2, 通过了第0个障碍物, 使用了 2.26s
  5. 队友1, 通过了第1个障碍物, 使用了 1.542s
  6. 队友0, 通过了第1个障碍物, 使用了 2.154s
  7. 队友2, 通过了第1个障碍物, 使用了 2.556s
  8. 队友1, 通过了第2个障碍物, 使用了 1.426s
  9. 队友2, 通过了第2个障碍物, 使用了 2.603s
  10. 队友0, 通过了第2个障碍物, 使用了 2.784s

代码:

  1. package com.huai.thread;
  2. import java.util.Random;
  3. import java.util.concurrent.BrokenBarrierException;
  4. import java.util.concurrent.CyclicBarrier;
  5. public class CyclicBarrierTest {
  6. public static void main(String[] args) {
  7. CyclicBarrier barrier = new CyclicBarrier(3);
  8. for(int i = 0; i < barrier.getParties(); i++){
  9. new Thread(new MyRunnable(barrier), "队友"+i).start();
  10. }
  11. System.out.println("main function is finished.");
  12. }
  13. private static class MyRunnable implements Runnable{
  14. private CyclicBarrier barrier;
  15. public MyRunnable(CyclicBarrier barrier){
  16. this.barrier = barrier;
  17. }
  18. @Override
  19. public void run() {
  20. for(int i = 0; i < 3; i++) {
  21. try {
  22. Random rand = new Random();
  23. int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数
  24. Thread.sleep(randomNum);
  25. System.out.println(Thread.currentThread().getName() + ", 通过了第"+i+"个障碍物, 使用了 "+((double)randomNum/1000)+"s");
  26. this.barrier.await();
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. } catch (BrokenBarrierException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }
  34. }
  35. }

总结:CountDownLatch和CyclicBarrier都有让多个线程等待同步然后再开始下一步动作的意思,但是CountDownLatch的下一步的动作实施者是主线程,具有不可重复性;而CyclicBarrier的下一步动作实施者还是“其他线程”本身,具有往复多次实施动作的特点。

原文链接:https://blog.csdn.net/liangyihuai/article/details/83106584

JUC之CountDownLatch和CyclicBarrier的区别 (转)的更多相关文章

  1. CountDownLatch和CyclicBarrier的区别

    [CountDownLatch.CyclicBarrier和Semaphore]http://www.cnblogs.com/dolphin0520/p/3920397.html   [CountDo ...

  2. CountDownLatch和CyclicBarrier的区别(转)

    在网上看到很多人对于CountDownLatch和CyclicBarrier的区别简单理解为CountDownLatch是一次性的,而CyclicBarrier在调用reset之后还可以继续使用.那如 ...

  3. JUC(3)---CountDownLatch、CyclicBarrier和AQS

    CountDownLatch可以让一个线程等待其他线程完成了各自的工作之后再执行.比如说一个切菜,一个人切肉,都准备完毕之后才能炒肉. 构造方法: public CountDownLatch(int ...

  4. 【对线面试官】CountDownLatch和CyclicBarrier的区别

    <对线面试官>系列目前已经连载31篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...

  5. 7,CountDownLatch 与 CyclicBarrier 的 区别

    CountDownLatch : 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDo ...

  6. JUC——线程同步辅助工具类(Semaphore,CountDownLatch,CyclicBarrier)

    锁的机制从整体的运行转态来讲核心就是:阻塞,解除阻塞,但是如果仅仅是这点功能,那么JUC并不能称为一个优秀的线程开发框架,然而是因为在juc里面提供了大量方便的同步工具辅助类. Semaphore信号 ...

  7. CountDownLatch和CyclicBarrier区别及用法的demo

    javadoc里面的描述是这样的. CountDownLatch: A synchronization aid that allows one or more threads to wait unti ...

  8. CountDownLatch,CyclicBarrier,Semaphore

    CountDownLatch是倒数,doneSignal = new CountDownLatch(LATCH_SIZE);赋初值后,在主线程中等待doneSignal.await();其它线程中,每 ...

  9. Java并发包5--同步工具CountDownLatch、CyclicBarrier、Semaphore的实现原理解析

    前言: JUC中提供了很多同步工具类,比如CountDownLatch.CyclicBarrier.Semaphore等,都可以作用同步手段来实现多线程之间的同步效果 一.CountDownLatch ...

随机推荐

  1. MySQL中使用group by 是总是出现1055的错误

    因为在MySQL中使用group by 是总是出现1055的错误,这就导致了必须去查看是什么原因了,查询了相关的资料,现在将笔记记录下来,以便后面可以参考使用: sql_mode:简而言之就是:它定义 ...

  2. 从零开始一个个人博客 by asp.net core and angular(一)

    这是一个个人叙述自己建设博客的帖子,既然是第一篇那肯定是不牵扯代码了,主要讲一下大体的东西,微软最新的web框架应该就数asp.net core 3.1了这是一个长期支持版,而且是跨平台又开源版本,所 ...

  3. Java实体对象为什么要实现Serializable接口?

    前言 Java实体对象为什么一定要实现Serializable接口呢?在学JavaSE的时候有些实体对象不实现Serializable不是也没什么影响吗? 最近在学习mybatis的时候发现,老师写的 ...

  4. Unity容器实现AOP面向切面编程

    为什么要有AOP 需求总是变化的,比如经常会对一些方法后期增加日志.异常处理.权限.缓存.事务的处理,遇到这种情况我们往往只能修改类. 为了应对变化,我们常常使用设计模式解决,但是也有其局限性:设计模 ...

  5. Java操作RocketMQ

    第一步:导入依赖 <dependency> <groupId>com.alibaba.rocketmq</groupId> <artifactId>ro ...

  6. JavaSE学习笔记(12)---线程

    JavaSE学习笔记(12)---线程 多线程 并发与并行 并发:指两个或多个事件在同一个时间段内发生. 并行:指两个或多个事件在同一时刻发生(同时发生). 在操作系统中,安装了多个程序,并发指的是在 ...

  7. Windows通过DOS命令行设置IP地址

    @rem 设置固定IP地址netsh interface ip set address "本地连接" static 192.168.1.200 255.255.255.0 192. ...

  8. 最小生成树算法总结(Kruskal,Prim)

    今天复习最小生成树算法. 最小生成树指的是在一个图中选择n-1条边将所有n个顶点连起来,且n-1条边的权值之和最小.形象一点说就是找出一条路线遍历完所有点,不能形成回路且总路程最短. Kurskal算 ...

  9. 报表生成(POI,jquery.table2excel.js,Echarts)

    最近公司要弄个报表相关的功能,话不多说,先上图 前一种是POI 生成的,后一种是Echarts生成的.报表我想大家都不陌生,基本上在公司业务中都会使用到.先说说POI,jquery.table2exc ...

  10. 深度优先搜索DFS---最优子序列求和问题(1)

    题目: 给定N 个整数(可能有负数),从中选择 K个数,使得这 K个数之和恰好等于一个给定的整数 X:如果有多种方案,那么选择它们中元素平方和最大的一个.例如,从4个整数{ 2, 3, 3 ,4}中选 ...