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

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

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

备注:这里我们使用主线程(即main函数)来创建CountDown和CyclicBarrier对象。所以上文将线程分为“主线程”和“其它线程”两类,主要是便于大家理解。需要提醒读者的是,不单单是主线程可以创建该对象,其它当前正在运行的线程也可以创建CountDown和CyclicBarrier对象,此时该current thread扮演了“主线程”的角色。因此,更加准确的方式是将线程分为“当前线程”和“其它线程”,前者表示创建CountDown和CyclicBarrier对象的线程。希望这个备注没有给大家带来更大的困惑。

下面举例说明:

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

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

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

CountDownLatch的代码:

import java.util.Random;
import java.util.concurrent.CountDownLatch;public class CountDownLatchTest {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(4);for(int i = 0; i < latch.getCount(); i++){new Thread(new MyThread(latch), "player"+i).start();}System.out.println("正在等待所有玩家准备好");latch.await();System.out.println("开始游戏");}private static class MyThread implements Runnable{private CountDownLatch latch ;public MyThread(CountDownLatch latch){this.latch = latch;}@Overridepublic void run() {try {Random rand = new Random();int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数Thread.sleep(randomNum);System.out.println(Thread.currentThread().getName()+" 已经准备好了, 所使用的时间为 "+((double)randomNum/1000)+"s");latch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}}
}

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

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

main function is finished.
队友1, 通过了第0个障碍物, 使用了 1.432s
队友0, 通过了第0个障碍物, 使用了 1.465s
队友2, 通过了第0个障碍物, 使用了 2.26s
队友1, 通过了第1个障碍物, 使用了 1.542s
队友0, 通过了第1个障碍物, 使用了 2.154s
队友2, 通过了第1个障碍物, 使用了 2.556s
队友1, 通过了第2个障碍物, 使用了 1.426s
队友2, 通过了第2个障碍物, 使用了 2.603s
队友0, 通过了第2个障碍物, 使用了 2.784s

代码:

package com.huai.thread;import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierTest {public static void main(String[] args) {CyclicBarrier barrier = new CyclicBarrier(3);for(int i = 0; i < barrier.getParties(); i++){new Thread(new MyRunnable(barrier), "队友"+i).start();}System.out.println("main function is finished.");}private static class MyRunnable implements Runnable{private CyclicBarrier barrier;public MyRunnable(CyclicBarrier barrier){this.barrier = barrier;}@Overridepublic void run() {for(int i = 0; i < 3; i++) {try {Random rand = new Random();int randomNum = rand.nextInt((3000 - 1000) + 1) + 1000;//产生1000到3000之间的随机整数Thread.sleep(randomNum);System.out.println(Thread.currentThread().getName() + ", 通过了第"+i+"个障碍物, 使用了 "+((double)randomNum/1000)+"s");this.barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}}
}

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

为了文章的完整性,补充下面一句话:
** 为了将上面的“通俗理解”进一步拓展,将前文中“主线程”替换成“当前线程”。因为创建和启动CountDownLatch和CyclicBarrier的是不仅仅是main线程,也可以是任意一个线程,这里使用当前线程来代替主线程这样的概念。**。希望这样的描述不会给大家带来额外的困惑。

Java的CountDownLatch和CyclicBarrier的理解和区别相关推荐

  1. 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...

  2. CountDownLatch、CyclicBarrier、Semaphore的区别,你知道吗?

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:是时候扔掉Postman了,又一个被低估的IDEA插件出来了...个人原创+1博客:点击前往,查看更多 链接:h ...

  3. 谈谈CountDownLatch和CyclicBarrier

    Java中CountDownLatch和CyclicBarrier都是用来做多线程同步的.下面分析一下他们功能的异同. CountDownLatch CountDownLatch基于AQS(同步器Ab ...

  4. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析

    1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...

  5. Java并发编程之CountDownLatch、CyclicBarrier和Semaphore

    前言 本文为对CountDownLatch.CyclicBarrier.Semaphore的整理使用 CountDownLatch CountDownLatch类位于java.util.concurr ...

  6. Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore

    2019独角兽企业重金招聘Python工程师标准>>> 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarr ...

  7. JAVA所有选手就位后比赛开始_Java多线程-CountDownLatch、CyclicBarrier、Semaphore

    上次简单了解了多线程中锁的类型,今天要简单了解下多线程并发控制的一些工具类了. 1. 概念说明: CountDownLatch:相当于一个待执行线程计数器,当计数减为零时表示所有待执行线程都已执行完毕 ...

  8. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    2019独角兽企业重金招聘Python工程师标准>>> Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一 ...

  9. Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger

    一.引言 Semaphore               :一个计数信号量 CountDownLatch          :一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线 ...

最新文章

  1. ASP .NET Core MVC 控制器中获取当前登录用户
  2. tar打包及打包并压缩
  3. 计算机组成原理访问失效,北京科技大学2013年硕士学位研究生入学考试试题(计算机组成原理)...
  4. 无法加载指定的元数据资源(转载)
  5. MySQL分区表概念以及优缺点
  6. LeetCode MySQL 615. 平均工资:部门与公司比较(over窗口函数)
  7. MVC3.0与C#截取字符串
  8. 这几个刺激的公众号 能让你怀疑人生
  9. BZOJ3091 城市旅行
  10. java连接数据库的详细步骤?
  11. 阿里 酷家乐:实习生面试
  12. 网站实现GNSS数据批量下载
  13. JS细胞分裂递归案例
  14. couch base使用记录
  15. 2022年场(厂)内专用机动车辆安全管理考试模拟100题模拟考试平台操作
  16. 值得收藏的22个搜索下载免费PDF电子书的网站
  17. 写java代码用什么软件好,重要概念一网打尽!
  18. MoveIt教程[20]:TRAC-IK Kinematics Solver
  19. SM3算法python实现
  20. 前端面试题:JS中的原型和原型链

热门文章

  1. python读写文件绝对路径_[Spark][Python]对HDFS 上的文件,采用绝对路径,来读取获得 RDD...
  2. 如何用git连接mysql_phpstorm神器之连接使用GitMySQL
  3. Netbeans配置Java SE嵌入式平台(树莓派)
  4. Keepalived双主模型中vrrp_script中权重改变故障排查
  5. Spring框架中的设计模式(二)
  6. 3D-HEVC视频编码技术
  7. POJ 2190 模拟
  8. Linux系统下wetty安装和使用说明
  9. bst latex 最大作者数_latex bst文件怎么用
  10. opc客户端_组态王作为OPC服务器的使用介绍,欢迎读者阅读