一 概念:
1.在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join方法,让主线程等待被join的线程执行完之后,主线程才能继续往下执行。
当然,使用线程间消息通信机制也可以完成。其实,java并发工具类中为我们提供了类似“倒计时”这样的工具类,可以十分方便的完成所说的这种业务场景。

主要方法:

  1. await() throws InterruptedException:调用该方法的线程等到构造方法传入的N减到0的时候,才能继续往下执行;
  2. await(long timeout, TimeUnit unit):与上面的await方法功能一致,只不过这里有了时间限制,调用该方法的线程等到指定的timeout时间后,不管N是否减至为0,都会继续往下执行
  3. countDown():使CountDownLatch初始值N减1;
  4. long getCount():获取当前CountDownLatch维护的值;

2.为了能够理解CountDownLatch,举一个很通俗的例子:

有六名运动员和一名裁判,运动员必须等待裁判枪声响起才能开始比赛,同时裁判也必须等运动员都准备完毕,才能发起比赛,裁判员在终点会为这6个运动员分别计时,可以想象没当一个运动员到达终点的时候,对于裁判员来说就少了一个计时任务。直到所有运动员都到达终点了,裁判员的任务也才完成。这6个运动员可以类比成6个线程。

public class CountDownLatchDemo {private static CountDownLatch readySignal = new CountDownLatch(6);  // 表示6名运动员是否准备就绪private static CountDownLatch startSignal = new CountDownLatch(1);  // 裁判发起比赛枪声private static CountDownLatch endSignal = new CountDownLatch(6);  // 表示6名运动员是否到达终点public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(6);for (int i = 0; i < 6; i++) {executorService.execute(() -> {try {System.out.println(Thread.currentThread().getName() + " 运动员准备完成!!!");readySignal.countDown();readySignal.await();startSignal.await();System.out.println(Thread.currentThread().getName() + " 正在全力冲刺");System.out.println(Thread.currentThread().getName() + " 到达终点");endSignal.countDown();} catch (InterruptedException e) {e.printStackTrace();}});}readySignal.await();  // 等待全部运动员准备完成System.out.println("所有运动员准备完成!!!裁判员发号施令啦!!!");startSignal.countDown();endSignal.await();System.out.println("所有运动员到达终点,比赛结束!");executorService.shutdown();}
}

运行结果:

pool-1-thread-1 运动员等待裁判员响哨!!!
pool-1-thread-2 运动员等待裁判员响哨!!!
pool-1-thread-2 运动员准备完成!!!
pool-1-thread-3 运动员等待裁判员响哨!!!
pool-1-thread-1 运动员准备完成!!!
pool-1-thread-3 运动员准备完成!!!
pool-1-thread-4 运动员等待裁判员响哨!!!
pool-1-thread-4 运动员准备完成!!!
pool-1-thread-5 运动员等待裁判员响哨!!!
pool-1-thread-5 运动员准备完成!!!
pool-1-thread-6 运动员等待裁判员响哨!!!
pool-1-thread-6 运动员准备完成!!!
所有运动员准备完成!!!裁判员发号施令啦!!!
pool-1-thread-6 正在全力冲刺
pool-1-thread-4 正在全力冲刺
pool-1-thread-6 到达终点
pool-1-thread-5 正在全力冲刺
pool-1-thread-5 到达终点
pool-1-thread-3 正在全力冲刺
pool-1-thread-1 正在全力冲刺
pool-1-thread-1 到达终点
pool-1-thread-2 正在全力冲刺
pool-1-thread-2 到达终点
pool-1-thread-3 到达终点
pool-1-thread-4 到达终点
所有运动员到达终点,比赛结束!Process finished with exit code 0

二. 循环栅栏:CyclicBarrier

CyclicBarrier也是一种多线程并发控制的实用工具,和CountDownLatch一样具有等待计数的功能,但是相比于CountDownLatch功能更加强大。

下面来看下CyclicBarrier的主要方法:

  1. await() throws InterruptedException, BrokenBarrierException // 等到所有的线程都到达指定的临界点
  2. await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException,TimeoutException // 与上面的await方法功能基本一致,只不过这里有超时限制,阻塞等待直至到达超时时间为止
  3. int getNumberWaiting() // 获取当前有多少个线程阻塞等待在临界点上
  4. boolean isBroken() // //用于查询阻塞等待的线程是否被中断

//将屏障重置为初始状态。如果当前有线程正在临界点等待的话,将抛出BrokenBarrierException。
void reset()
另外需要注意的是,CyclicBarrier提供了这样的构造方法:

public CyclicBarrier(int parties, Runnable barrierAction)

使用CyclicBarrier同样可以实现上边的需求:

public class CylicBarrierDemo {public static void main(String[] args) throws BrokenBarrierException, InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(6);CyclicBarrier barrier = new CyclicBarrier(6, () -> {System.out.println("所有运动员准备完成!!!裁判员发号施令啦!!!");});CyclicBarrier endBarrier = new CyclicBarrier(6, () -> {System.out.println("所有运动员到达终点,比赛结束!");});for (int i = 0; i < 6; i++) {executorService.submit(()->{try {System.out.println(Thread.currentThread().getName() + " 运动员等待裁判员响哨!!!");System.out.println(Thread.currentThread().getName() + " 运动员准备完成!!!");barrier.await();System.out.println(Thread.currentThread().getName() + " 正在全力冲刺");System.out.println(Thread.currentThread().getName() + " 到达终点");endBarrier.await();} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}});}}
}

输出:

pool-1-thread-1 运动员准备完成!!!
pool-1-thread-3 运动员等待裁判员响哨!!!
pool-1-thread-3 运动员准备完成!!!
pool-1-thread-2 运动员等待裁判员响哨!!!
pool-1-thread-2 运动员准备完成!!!
pool-1-thread-4 运动员等待裁判员响哨!!!
pool-1-thread-4 运动员准备完成!!!
pool-1-thread-5 运动员等待裁判员响哨!!!
pool-1-thread-5 运动员准备完成!!!
pool-1-thread-6 运动员等待裁判员响哨!!!
pool-1-thread-6 运动员准备完成!!!
所有运动员准备完成!!!裁判员发号施令啦!!!
pool-1-thread-6 正在全力冲刺
pool-1-thread-6 到达终点
pool-1-thread-1 正在全力冲刺
pool-1-thread-1 到达终点
pool-1-thread-2 正在全力冲刺
pool-1-thread-2 到达终点
pool-1-thread-5 正在全力冲刺
pool-1-thread-5 到达终点
pool-1-thread-4 正在全力冲刺
pool-1-thread-4 到达终点
pool-1-thread-3 正在全力冲刺
pool-1-thread-3 到达终点
所有运动员到达终点,比赛结束!

倒计时器CountDownLatch 和 循环栅栏:CyclicBarrier相关推荐

  1. 信号量semaphore 读写锁ReadWriteLock 倒计时器CountDownLatch 循环栅栏 CyclicBarrier 线程阻塞工具类LockSupport...

    信号量semaphore    允许多个线程同时访问 读写锁ReadWriteLock   在频繁的读写耗时中,读之间不阻塞 倒计时器CountDownLatch    obj = new Count ...

  2. 非常有用的并发控制-循环栅栏CyclicBarrier

    转载自 非常有用的并发控制-循环栅栏CyclicBarrier 昨天我讲了倒计时器CountDownLatch的应用,它是阻塞线程直到计时器归0的一种等待方式.今天讲的这个循环栅栏CyclicBarr ...

  3. Java多线程编程-(6)-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier

    前几篇: Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-线程本地Th ...

  4. java多线程之倒计时器CountDownLatch

    示例一. 原文:https://www.relaxheart.cn/to/master/blog?uuid=83 CountDownLatch是一个非常实用的多线程控制工具类.常用的就下面几个方法: ...

  5. 【高并发】JUC中的循环栅栏CyclicBarrier的6种使用场景

    1.概述 转载:添加链接描述 2.CyclicBarrier简介 CyclicBarrier通常称为循环屏障.它和CountDownLatch很相似,都可以使线程先等待然后再执行.不过CountDow ...

  6. Java并发编程系列学习_CountDownLatch倒计时器CyclicBarrier循环栅栏

    一.倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join方 ...

  7. CyclicBarrie(循环栅栏)的作用与用法

    CyclicBarrie的作用与用法 一.CyclicBarrie的作用 CyclicBarrier循环栅栏(循环屏障)是一个多线程同步的辅助工具类,它允许一组线程在到达某个等待屏障点(common ...

  8. 非常有用的并发控制-倒计时器CountDownLatc

    转载自 非常有用的并发控制-倒计时器CountDownLatch CountDownLatch见名思义,即倒计时器,是多线程并发控制中非常有用的工具类,它可以控制线程等待,直到倒计时器归0再继续执行. ...

  9. 循环计数_倒计数器:CountDownLatch | 循环栅栏:CyclicBarrier

    倒计数器:CountDownLatch CountDownLatch 从名字就可以看出其作用:初始化一个计数,然后每次递减,直至为0,然后触发一个动作.只有一个带参构造器: CountDownLatc ...

最新文章

  1. Multithreading in Java
  2. ANT集成SVNANT访问SVN(Subversion)
  3. 图神经网络(一)图信号处理与图卷积神经网络(1)矩阵乘法的三种方式
  4. Linux基本命令+Makefile
  5. SOA为什么不“香”了? | 大咖说中台
  6. E20170618-hm
  7. 新书上市|这套北大数学系青睐的数学科普书,又添新成员
  8. python-数据结构-大学生-航空订票系统
  9. tableau中快速实现环比增长率计算
  10. C/C++编程学习 - 第16周 ⑦ 三人行必有我师
  11. 如何通过数据分析进行活动效果评估
  12. html的英文全称怎么读,HTML标签英文全称对照.doc
  13. 面向消费者的产品(To C 类)、面向企业的产品(To B 类)这2类产品在品牌营销方式上的区别?
  14. 最全解读 |《数据安全法(草案)》热点解析(上)
  15. rabbitmq消息发布mandatory参数
  16. CL210红帽OpenStack平台架构--介绍overcloud
  17. 【水环境病原菌数据库开发心得】
  18. chfs文件共享工具
  19. James Charles || 一夜掉粉三百万,油管美妆区顶级流量的覆灭
  20. PCB设计中的焊盘设计标准

热门文章

  1. 计算机图形学——OpenGL学习系列之绘制3D下的小桌子
  2. 迅为IMX6Q四核核心板商业级|工业级|IMX6Plus版本|IMX6D双核核心板
  3. Windows Bat批处理技巧之管理员权限运行
  4. 记 cisco ucs b200 m3 部署esxi 6.7
  5. UI设计师需要学习什么呢?
  6. linux下装QQ,64位系统
  7. 脑机接口专栏 | 利用黎曼几何分析EEG脑电信号(二)
  8. 【今日CV 计算机视觉论文速览 第93期】Wed, 3 Apr 2019
  9. U盘格式化了还能恢复吗?要怎么做呢?
  10. c语言进程控制实验报告,操作系统进程的创建与控制实验报告.doc