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. 算法练习LeetCode初级算法之数组

    删除数组中的重复项 官方解答: 旋转数组 存在重复元素 只出现一次的数     官方解答:  同一个字符进行两次异或运算就会回到原来的值 两个数组的交集 II import java.util.Arr ...

  2. [原]CentOS 7.2 1511部署L2TP/IPsec服务器及客户端

    快过年了,感觉从去年开始,我们公司就变成了“别人的公司”,基本上提前一星期就放假了,好开心.正好可以利用这一段时间,把前段时间一些疑惑的问题解决下:) 然而挡在面前的一个拦路虎是:很多时候不能愉快的G ...

  3. PHP开发——函数

    函数的定义 l  函数是一段命名的代码段. 函数可以减轻工作量,减少重复的代码,方便后期维护. 函数的参数 l  实参:调用函数时,传递的参数就是实参,含有真正数据的. l  形参:定义函数时的参数. ...

  4. linearlayout 中ImageView 居中等问题

    linearlayout  下的子控件使用android:layout_gravity=”center”  控件居左,没有达到居中的效果, 父窗体只能指定一种控件摆放方向 横向还是竖向 下面我弄了三个 ...

  5. Hello SIP Protocol

    SIP Request Line Request-Line = Method SP Request-URI SP SIP-Version CRLFMethod:        1. REGISTER ...

  6. 网络虚拟化技术(二): TUN/TAP MACVLAN MACVTAP (转)

    网络虚拟化技术(二): TUN/TAP MACVLAN MACVTAP 27 March 2013 TUN 设备 TUN 设备是一种虚拟网络设备,通过此设备,程序可以方便得模拟网络行为.先来看看物理设 ...

  7. ORM常用字段介绍

    Django中的ORM Django项目使用MySQL数据库 1. 在Django项目的settings.py文件中,配置数据库连接信息: DATABASES = { "default&qu ...

  8. PYthon第十二天

    1. 生成器 生成器的本质是迭代器, 最简单的生成器函数如下: def foo(x): 1-4行定义了一个简单的生成器函数 yield x+1 yield 和 return 不同, return 结束 ...

  9. MyAdvice 填充方法(在原有方法上添加方法)

    //applicationContext.xml配置文件  /UserServiceImp继承于UserService接口 <!-- 1 配置目标对象-->    <bean nam ...

  10. MySQL—查询某时间范围的数据

    -- 查询今天的数据 select * from `user` where to_days(birthday) = to_days(CURDATE()); -- 查询昨天的数据 select * fr ...