CountDownLatch与CyclicBarrier
文章目录
- 倒计时器CountDownLatch
- 循环栅栏CyclicBarrier
- CountDownLatch与CyclicBarrier的比较
倒计时器CountDownLatch
public CountDownLatch(int count)
构造方法会传入一个整型数N,之后调用CountDownLatch的countDown
方法会对N减一,直到N减到0的时候,当前调用await
方法的线程继续执行。
CountDownLatch的方法不是很多,将它们一个个列举出来:
- await() throws InterruptedException:调用该方法的线程等到构造方法传入的N减到0的时候,才能继续往下执行;
- await(long timeout, TimeUnit unit):与上面的await方法功能一致,只不过这里有了时间限制,调用该方法的线程等到指定的timeout时间后,不管N是否减至为0,都会继续往下执行;
- countDown():使CountDownLatch初始值N减1;
- long getCount():获取当前CountDownLatch维护的值;
下面用一个具体的例子来说明CountDownLatch的具体用法:
public class CountDownLatchDemo {private static CountDownLatch startSignal = new CountDownLatch(1);//用来表示裁判员需要维护的是6个运动员private static CountDownLatch endSignal = new CountDownLatch(6);public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(6);System.out.println("各位运动员准备啦!!!");for (int i = 0; i < 6; i++) {executorService.execute(() -> {try {System.out.println(Thread.currentThread().getName() + " 运动员等待裁判员响哨!!!");// 确保所有运动员准备完毕Thread.sleep(1000);startSignal.await();System.out.println(Thread.currentThread().getName() + " 正在全力冲刺");endSignal.countDown();System.out.println(Thread.currentThread().getName() + " 到达终点");} catch (InterruptedException e) {e.printStackTrace();}});}//将executorService转换为ThreadPoolExecutor,ThreadPoolExecutor有方法 getActiveCount()可以得到当前活动线程数int threadCount = ((ThreadPoolExecutor)executorService).getActiveCount();if (threadCount == 6) {System.out.println("裁判员响哨...");startSignal.countDown();endSignal.await();System.out.println("所有运动员到达终点,比赛结束!");}executorService.shutdown();}}
各位运动员准备啦!!!
pool-1-thread-1 运动员等待裁判员响哨!!!
pool-1-thread-3 运动员等待裁判员响哨!!!
pool-1-thread-2 运动员等待裁判员响哨!!!
pool-1-thread-5 运动员等待裁判员响哨!!!
pool-1-thread-4 运动员等待裁判员响哨!!!
pool-1-thread-6 运动员等待裁判员响哨!!!
裁判员响哨...
pool-1-thread-5 正在全力冲刺
pool-1-thread-5 到达终点
pool-1-thread-6 正在全力冲刺
pool-1-thread-2 正在全力冲刺
pool-1-thread-2 到达终点
pool-1-thread-1 正在全力冲刺
pool-1-thread-1 到达终点
pool-1-thread-3 正在全力冲刺
pool-1-thread-3 到达终点
pool-1-thread-4 正在全力冲刺
pool-1-thread-6 到达终点
pool-1-thread-4 到达终点
所有运动员到达终点,比赛结束!
另外,需要注意的是,当调用CountDownLatch的countDown方法时,当前线程是不会被阻塞,会继续往下执行,比如在该例中会继续输出pool-1-thread-4 到达终点
。
循环栅栏CyclicBarrier
CyclicBarrier也是一种多线程并发控制的实用工具,和CountDownLatch一样具有等待计数的功能,但是相比于CountDownLatch功能更加强大。
//等到所有的线程都到达指定的临界点
await() throws InterruptedException, BrokenBarrierException //与上面的await方法功能基本一致,只不过这里有超时限制,阻塞等待直至到达超时时间为止
await(long timeout, TimeUnit unit) throws InterruptedException,
BrokenBarrierException, TimeoutException //获取当前有多少个线程阻塞等待在临界点上
int getNumberWaiting()//用于查询阻塞等待的线程是否被中断
boolean isBroken()//将屏障重置为初始状态。如果当前有线程正在临界点等待的话,将抛出BrokenBarrierException。
void reset()
另外需要注意的是,CyclicBarrier提供了这样的构造方法:
public CyclicBarrier(int parties, Runnable barrierAction)
可以用来,当指定的线程都到达了指定的临界点的时,接下来执行的操作可以由barrierAction传入即可。
一个例子
下面用一个简单的例子,来看下CyclicBarrier的用法,我们来模拟下上面的运动员的例子。
public class CyclicBarrierDemo {//指定必须有6个运动员到达才行private static CyclicBarrier barrier = new CyclicBarrier(6, () ->System.out.println("所有运动员入场,裁判员一声令下!!!!!"));public static void main(String[] args) {System.out.println("运动员准备进场,全场欢呼............");ExecutorService service = Executors.newFixedThreadPool(6);for (int i = 0; i < 6; i++) {service.execute(() -> {try {System.out.println(Thread.currentThread().getName() + " 运动员,进场");barrier.await();System.out.println(Thread.currentThread().getName() + " 运动员出发");} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}});}}}
输出结果
运动员准备进场,全场欢呼............
pool-1-thread-1 运动员,进场
pool-1-thread-4 运动员,进场
pool-1-thread-3 运动员,进场
pool-1-thread-2 运动员,进场
pool-1-thread-6 运动员,进场
pool-1-thread-5 运动员,进场
所有运动员入场,裁判员一声令下!!!!!
pool-1-thread-5 运动员出发
pool-1-thread-1 运动员出发
pool-1-thread-6 运动员出发
pool-1-thread-3 运动员出发
pool-1-thread-2 运动员出发
pool-1-thread-4 运动员出发
从输出结果可以看出,当6个运动员(线程)都到达了指定的临界点(barrier)时候,才能继续往下执行,否则,则会阻塞等待在调用await()
处
CountDownLatch与CyclicBarrier的比较
CountDownLatch与CyclicBarrier都是用于控制并发的工具类,都可以理解成维护的就是一个计数器,但是这两者还是各有不同侧重点的:
- CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;CountDownLatch强调一个线程等多个线程完成某件事情。CyclicBarrier是多个线程互等,等大家都完成,再携手共进。
- 调用CountDownLatch的countDown方法后,当前线程并不会阻塞,会继续往下执行;而调用CyclicBarrier的await方法,会阻塞当前线程,直到CyclicBarrier指定的线程全部都到达了指定点的时候,才能继续往下执行;
- CountDownLatch方法比较少,操作比较简单,而CyclicBarrier提供的方法更多,比如能够通过getNumberWaiting(),isBroken()这些方法获取当前多个线程的状态,并且CyclicBarrier的构造方法可以传入barrierAction,指定当所有线程都到达时执行的业务功能;
- CountDownLatch是不能复用的,而CyclicLatch是可以复用的。
CountDownLatch与CyclicBarrier相关推荐
- Java并发编程之CountDownLatch、CyclicBarrier和Semaphore
前言 本文为对CountDownLatch.CyclicBarrier.Semaphore的整理使用 CountDownLatch CountDownLatch类位于java.util.concurr ...
- Java的CountDownLatch和CyclicBarrier的理解和区别
CountDownLatch和CyclicBarrier的功能看起来很相似,不易区分,有一种谜之的神秘.本文将通过通俗的例子并结合代码讲解两者的使用方法和区别. CountDownLatch和Cycl ...
- 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
2019独角兽企业重金招聘Python工程师标准>>> 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarr ...
- 秒懂 CountDownLatch 与 CyclicBarrier 使用场景
作者 | pony-zi 来源 | https://blog.csdn.net/zzg1229059735/article/details/61191679 相信每个想深入了解多线程开发的Java开发 ...
- 并发工具类:CountDownLatch、CyclicBarrier、Semaphore
在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...
- Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析
1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...
- JUC 中的多线程协作工具类:CountDownLatch 和 CyclicBarrier
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:干掉 Navicat:这个 IDEA 的兄弟真香!个人原创100W+访问量博客:点击前往,查看更多 最近在学习 ...
- CountDownLatch、CyclicBarrier、Semaphore的区别,你知道吗?
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:是时候扔掉Postman了,又一个被低估的IDEA插件出来了...个人原创+1博客:点击前往,查看更多 链接:h ...
- JAVA所有选手就位后比赛开始_Java多线程-CountDownLatch、CyclicBarrier、Semaphore
上次简单了解了多线程中锁的类型,今天要简单了解下多线程并发控制的一些工具类了. 1. 概念说明: CountDownLatch:相当于一个待执行线程计数器,当计数减为零时表示所有待执行线程都已执行完毕 ...
最新文章
- 科大星云诗社动态20210222
- linux echo写php编码,linux使用和基础操作(示例代码)
- RedOffice教你DIY环保小日历
- web服务压力测试)有效的压力测试系统将应用以下这些关键条件
- Javascript中的arguments数组对象
- 1005:I Think I Need a Houseboat-poj
- easyui验证:validatebox
- 领导力十律_关于开放领导力的10个最受欢迎的故事
- 应对游戏业务的四大“崩溃”场景有妙招,安全畅玩不是梦!
- JAVA学习笔记-this隐式参数
- 实训作业 4(界面2)
- 微信小程序从入门到放弃(五)
- win7怎样在线升级到win10 win7直接升级win10详细教程
- springcloud+eureka简单的邮件监控
- C#递归算法使用案例——画树
- [附源码]SSM计算机毕业设计逸尘房屋销售管理系统JAVA
- 最常用算法汇总(一)
- 判断某键值是否存在[注册表操作]
- c语言光敏程序代码,ADC实验之光敏传感器
- 技术干货:Apache Pulsar 在移动云上的应用
热门文章
- LeetCode第176场周赛(Weekly Contest 176)解题报告
- Echarts x轴,y轴,文字大小设置.
- 不提拔你,就因为你只想把工作做好
- .idea文件夹是干嘛的
- oracle中图片是黑色的,黑色高清壁纸
- 计算机毕业设计Java电子商城系统(源码+系统+mysql数据库+lw文档)
- 基于公共交通大数据的城市交通系统对策模型体系研究
- 睡觉的时候让linux也不闲着
- 性能测试培训总结-axwin frame window:thumbprocess.exe 解决方法
- 多项式全家桶——Part.1 多项式加减乘