一.CountDownLatch的使用

CountDownLatch经常用于监听某些初始化操作,等初始化执行完毕后,再通知主线程继续工作。

CountDownLatch定义:

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行

下面我们来看下CountDownLatch的使用方法:

package com.bjsxt.height.concurrent019;import java.util.concurrent.CountDownLatch;public class UseCountDownLatch {public static void main(String[] args) {final CountDownLatch countDown = new CountDownLatch(2);Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {try {System.out.println("进入线程t1" + "等待其他线程处理完成...");countDown.await();System.out.println("t1线程继续执行...");} catch (InterruptedException e) {e.printStackTrace();}}},"t1");Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {try {System.out.println("t2线程进行初始化操作...");Thread.sleep(3000);System.out.println("t2线程初始化完毕,通知t1线程继续...");countDown.countDown();} catch (InterruptedException e) {e.printStackTrace();}}});Thread t3 = new Thread(new Runnable() {@Overridepublic void run() {try {System.out.println("t3线程进行初始化操作...");Thread.sleep(4000);System.out.println("t3线程初始化完毕,通知t1线程继续...");countDown.countDown();} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();t2.start();t3.start();      }
}
执行结果如下:进入线程t1  等待其他线程处理完成……
进入线程t3进行初始化操作……
进入线程t2进行初始化操作……
t3线程执行完毕。。。
t2线程执行完毕。。。
t1线程继续执行……

分析CountDownLatch:

运行程序我们会发现当我们在t1调用CountDownLatch的await()方法时,就好比我们调用了wait()方法,当前线程会处于阻塞状态,直到等到t2和t3完全执行完毕并且调用countDown()方法时,我们才能唤醒t1继续进行执行,CountDownLatch就好比一个计时器,我们可以让当前线程调用CountDownLatch中的await()方法进行等待,如果想让当前线程继续执行,我们必须让CountDownLatch获得初始化时候传入的构造参数个countDown()方法,我们才能继续执行。

CountDownLatch的使用场景:

在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。 这个时候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。

二.CyclicBarrier的使用

假设有一个场景,每个线程代表一个跑步的运动员,当运动员都准备好之后,才一起出发,只要有一个运动员还没有准备好,所有线程就一起等待。

CyclicBarrier的定义(来自百度):

CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。

下面我们来看CyclicBarrier 的使用小Demo:

package com.bjsxt.height.concurrent019;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class UseCyclicBarrier {static class Runner implements Runnable {  private CyclicBarrier barrier;  private String name;  public Runner(CyclicBarrier barrier, String name) {  this.barrier = barrier;  this.name = name;  }  @Override  public void run() {  try {  Thread.sleep(1000 * (new Random()).nextInt(5));  System.out.println(name + " 准备OK.");  barrier.await();  } catch (InterruptedException e) {  e.printStackTrace();  } catch (BrokenBarrierException e) {  e.printStackTrace();  }  System.out.println(name + " Go!!");  }  } public static void main(String[] args) throws IOException, InterruptedException {  CyclicBarrier barrier = new CyclicBarrier(3);  // 3 ExecutorService executor = Executors.newFixedThreadPool(3);  executor.submit(new Thread(new Runner(barrier, "zhangsan")));  executor.submit(new Thread(new Runner(barrier, "lisi")));  executor.submit(new Thread(new Runner(barrier, "wangwu")));  executor.shutdown();  }  }  
执行结果如下:
lisi 准备OK.
zhangsan 准备OK.
wangwu 准备OK.
wangwu Go!!
lisi Go!!
zhangsan Go!!

CyclicBarrier 分析结果:

上述程序我们创建了一个线程池,这个线程池中有三个线程,每个线程都传递了一个相同的CyclicBarrier 对象和运动员的名字,我们Runner类中的run方法使每一个进来的运动员都休眠0-5秒的时间,然后调用await()方法,就是说每个线程进来都需要进行等待,直到所有的CyclicBarrier 都处于准备好了的状态,所有线程才能统一开始执行!

CyclicBarrier 使用场景

  • CyclicBarrier可以用于多线程计算数据,最后合并计算结果的应用场景。比如我们用一个Excel保存了用户所有银行流水,每个Sheet保存一个帐户近一年的每笔银行流水,现在需要统计用户的日均银行流水,先用多线程处理每个sheet里的银行流水,都执行完之后,得到每个sheet的日均银行流水,最后,再用barrierAction用这些线程的计算结果,计算出整个Excel的日均银行流水。
  • 三.cyclicBarrier和CountDownLatch的区别

1、CountDownLatch简单的说就是一个线程等待,直到他所等待的其他线程都执行完成并且调用countDown()方法发出通知后,当前线程才可以继续执行。

2、cyclicBarrier是所有线程都进行等待,直到所有线程都准备好进入await()方法之后,所有线程同时开始执行!

3、CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。

4,、CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。如果被中断返回true,否则返回false。

多线程之CountDownLatch和CyclicBarrier的区别和用法相关推荐

  1. Java多线程同步屏障计算_Java多线程之CountDownLatch和CyclicBarrier同步屏障的使用

    一:CountDownLatch CountDownLatch是一个执行 完成任务线程数 的 倒数计数器.我们考虑这种情况:士兵晨练,必须全队士兵集合完毕才开始跑步.用程序描述就:在晨练线程中,逐个启 ...

  2. Java多线程之Synchronized和Lock的区别

    Java多线程之Synchronized和Lock的区别 目录: 原始构成 使用方法 等待是否可以中断 加锁是否公平 锁绑定多个条件Condition 小结:Lock相比较Synchronized的优 ...

  3. Java多线程之CountDownLatch用法

    Java多线程之CountDownLatch用法 本文目录: CountDownLatch基本概念 CountDownLatch案例:6个同学陆续离开教室后班长才可以关门 CountDownLatch ...

  4. CountDownLatch和CyclicBarrier的区别

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

  5. (十)java多线程之CountDownLatch

    目录 引言 理论 例子 打赏 本人邮箱: kco1989@qq.com 欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco github: https://gi ...

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

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

  7. java多线程下LongAdder、CountDownLatch、CyclicBarrier、Phaser 的用法

    前言 一文读懂java多线程下常用常考的阻塞方法LongAdder.CountDownLatch.CyclicBarrier.Phaser 包含演示代码 高并发模拟,性能比较实例代码 前言 LongA ...

  8. JAVA多线程之CountDownLatch

    前序: 上周测试给开发的同事所开发的模块提出了一个bug,并且还是偶现. 经过仔细查看代码,发现是在业务中启用了多线程,2个线程同时跑,但是新启动的2个线程必须保证一个完成之后另一个再继续运行,才能消 ...

  9. java多线程之CountDownLatch倒数闸门

    在多个线程进行协作时,一个常见的情景是一个线程需要等待另外的线程完成某些任务之后才能继续进行.在这种情况下,可以使用CountDownLatch类,CountDownLatch类相当于多个线程等待开启 ...

最新文章

  1. java双目运算符重载,c++类的单目和双目运算符的重定义
  2. bartender的安全策略不允许指定的用户执行此操作_MongoDB用户和角色解释系列(上)...
  3. 浅谈前端安全问题及策略
  4. [2018.12.26]BZOJ1022 [SHOI2008]小约翰的游戏John
  5. spring MVC请求处理类注解属性详解
  6. ASP.NET中PostBack和ViewState
  7. 使用Spring Security进行简单身份验证
  8. AJAX,JSON与MVC
  9. 程序执行原理(科普)
  10. golang学习的点点滴滴:if、switch使用
  11. javaweb体育赛事网上售票系统
  12. 通过BSSID连接WiFi
  13. linux源码编译ipk,OpenWrt-SDK-编译生成ipk软件包
  14. 互联网行业定制网站需要多少钱
  15. php 联合查询,多表联合查询
  16. 最简单优雅修改jupyter自带主题字体大小颜色(不需要插件不需要第三方theme)
  17. 网上打印文件怎么发给商家?怎么给商家发送打印资料
  18. PyCharm下载和安装
  19. 探秘手机距离传感器工作背后的那些事儿
  20. 【遇见CUDA】CUDA算法效率提升关键点概述

热门文章

  1. inuri .php id=,php常用函数(遇见就补充)
  2. mysql中文注入_SQL注入之Mysql报错注入
  3. 【OpenCV 例程200篇】94. 算术平均滤波器
  4. 【OpenCV 例程200篇】65. 图像锐化——Scharr 算子
  5. 【OpenCV 例程200篇】19. 图像的圆形遮罩
  6. mxnet深度学习(Symbol)
  7. windows rt c语言,有arm架构的windows平板吗??与x86的win有什么不同?arm写c语言怎样?
  8. python如何导入函数_Python导入(import)模块的方法
  9. js 给动态li添加动态点击事件
  10. Pytest跳过执行之@pytest.mark.skip()详解大全