CountDownLatch 和 CyclicBarrier 是并发编程中常用的辅助类,两者使用上有点类似,但又有不同。

一、CountDownLatch

  CountDownLatch 可是实现类似计数器的功能,比如一个线程 A 需要等待其余多个任务执行完毕后才能执行,此时可以使用这个工具类。

  构造器:

public CountDownLatch(int count) { }

  主要方法:

public void await() throws InterruptedException { };   // 调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; // 和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { }; // 将count值减1

  示例方法:

public static void main(String[] args) {

    final CountDownLatch latch = new CountDownLatch(2);

    new Thread() {
@Override
public void run() {
try {
System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep(3000);
System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start(); new Thread() {
@Override
public void run() {
try {
System.out.println("子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep(3000);
System.out.println("子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start(); try {
System.out.println("等待2个子线程执行完毕...");
latch.await();
System.out.println("2个子线程已经执行完毕");
System.out.println("继续执行主线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

  执行结果: 

子线程Thread-0正在执行
等待2个子线程执行完毕...
子线程Thread-1正在执行
子线程Thread-1执行完毕
子线程Thread-0执行完毕
2个子线程已经执行完毕
继续执行主线程
二、CyclicBarrier

  CyclicBarrier 可以称为回环栅,可以实现所有线程同时执行某动作的效果。比如跑步运动员在比赛前需要进行准备工作,等所有运动员都准备完毕后,同时开始比赛。

  构造器:

public CyclicBarrier(int parties) { }  // 设置线程数量
public CyclicBarrier(int parties, Runnable barrierAction) { } // 设置线程数量,并设置所有线程 await 执行完毕后的方法

  主要方法:

public int await() throws InterruptedException, BrokenBarrierException { };  // 挂起线程,直至所有线程达到 barrier 状态再执行
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { }; // 同上,挂起线程,等待一定的时间

  示例方法:

public class CyclicBarrierTest {

    public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println("所有运动员准备完毕,倒计时3秒后比赛开始...我是裁判:" + Thread.currentThread().getName()
+ ",当前时间:" + System.currentTimeMillis());
}
}); new Competition(barrier, "张三").start();
new Competition(barrier, "李四").start();
new Competition(barrier, "王五").start();
} /**
* 跑步比赛内容,所有人准备工作完成后,起跑
*/
static class Competition extends Thread { private CyclicBarrier cyclicBarrier; private String name; public Competition(CyclicBarrier cyclicBarrier, String name) {
this.cyclicBarrier = cyclicBarrier;
this.name = name;
} @Override
public void run() {
int time = new Random().nextInt(10);
System.out.println(name + "开始准备工作,预计耗时:" + time + "秒");
try {
// 准备中
Thread.sleep(time * 1000);
System.out.println(name + "准备完成,等待其他运动员完成");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
// 起跑倒计时
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(name + "已经起跑...当前时间:" + System.currentTimeMillis());
}
} }

  执行结果:

张三开始准备工作,预计耗时:5秒
王五开始准备工作,预计耗时:2秒
李四开始准备工作,预计耗时:6秒
王五准备完成,等待其他运动员完成
张三准备完成,等待其他运动员完成
李四准备完成,等待其他运动员完成
所有运动员准备完毕,倒计时3秒后比赛开始...我是裁判:Thread-1,当前时间:1548768695636
张三已经起跑...当前时间:1548768698637
王五已经起跑...当前时间:1548768698637
李四已经起跑...当前时间:1548768698637

  执行分析:

  三个运动员每个人是一个线程,执行比赛这一个动作。准备工作和起跑是比赛动作的两个部分,其中准备工作耗时不同,起跑动作又需要所有运动员都准备完毕才可以进行。线程启动后,每个运动员执行自身的准备工作,然后阻塞等待其余所有线程执行完准备工作(执行完 await 前序动作),再同时执行各自线程的剩余工作(起跑)。

图1 CyclicBarrier 执行过程分析

三、两者区别

1、CountDownLatch 不可重置,无法重用;CyclicBarrier 可以重置,允许重复使用。

2、CountDownLatch 等待对象是一个线程等待多个线程执行完毕后,再自身执行,而 CyclicBarrier 是多个线程之间相互等待,等所有线程执行到统一状态时,再同时执行后续动作。  

CountDownLatch 和 CyclicBarrier 的基本使用的更多相关文章

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

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...

  2. 并发工具类:CountDownLatch、CyclicBarrier、Semaphore

    在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...

  3. Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future

    CountDownLatch.CyclicBarrier.Semaphore.Callable.Future  都位于java.util.concurrent包下,其中CountDownLatch.C ...

  4. 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore

    前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...

  5. CountDownLatch,CyclicBarrier,Semaphore

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

  6. CountDownLatch、CyclicBarrier、Semaphore、Exchanger

    CountDownLatch: 允许N个线程等待其他线程完成执行.无法进行重复使用,只能用一次. 比如有2个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch ...

  7. CountDownLatch、CyclicBarrier和Semaphore

    转载:http://www.cnblogs.com/dolphin0520/p/3920397.html 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDown ...

  8. CountDownLatch和CyclicBarrier的区别

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

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

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

  10. CountDownLatch 和 CyclicBarrier 的运用及实现原理

    I.CountDownLatch 和 CyclicBarrier 的运用 CountDownlatch: 定义: 其是一个线程同步的辅助工具,通过它可以做到使一条线程一直阻塞等待,直到其他线程完成其所 ...

随机推荐

  1. java_16Arrays类

    1sort():对数组进行升序排列 public static void main(String[] args) { int[] arr= {2,43,6,7}; Arrays.sort(arr); ...

  2. angular2 学习

    一,angular2脚手架搭建 1,安装node 2,安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org 3,搭 ...

  3. rabbitmq初学之连接测试

    Login was refused using authentication mechanism PLAIN. 用户名或密码没有设置,或者错误

  4. git stash错误小记

    git出错小记 想要push代码,我们经常这样做. 1.查看状态 git status 2.隐藏本地编辑的新内容 git stash 3.拉远程的代码 git pull 这一步操作有的时候会报错,没有 ...

  5. 主键生成策略sequence

    http://blog.csdn.net/shanhuhau/article/details/24978253 表示:如果不写序列名,会走默认的序列 若写,则seq_表名_属性名

  6. 别人的Linux私房菜(4)安装CentOS7

    linux磁盘分区参考: 添加磁盘分区(总30G). BIOS boot 2MB 系统自定义文件系统 分区格式为主要分区 /boot 1GB  文件系统为xfs  主要分区 / 10GB 文件系统为x ...

  7. discover功能--自动发现主机

    discover功能,让监控的管理更加管理和自动化,现在来演示下如何使用discover功能自动发现主机 1.配置discover 2.在被侦测机上安装zabbix agent 安装完成后,修改配置( ...

  8. The First BoKe

    A.如何看待师生关系 说起师生关系,我们每个人都有不同的见解,但无一例外,师者,传道授业解惑也,老师的为学生传授的才能知识,是学生今后发展的宝贵财富,无论是从哪方面,都可以对学生起着积极向上的作用.而 ...

  9. VB.NET 定义多行文本字符的几种方式

    vbCrLf 在 .NET 刚刚推出的时候,VB作为一款被微软用来"衬托"C#的语言,在许多细节设计上远不如C#方便. 比如在C#中写一个多行文本,就有各种方式: string s ...

  10. 9.indicate、xutils、json

    json数据  页签详情页数据   public class TabData { public int retcode; public TabDetail data;//不是数组的话类型就是这个 pu ...