循环屏障CyclicBarrier以及和CountDownLatch的区别
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。
这个屏障之所以用循环修饰,是因为在所有的线程释放彼此之后,这个屏障是可以重新使用的(reset()方法重置屏障点)。这一点与CountDownLatch不同
CyclicBarrier
CyclicBarrier,让一组线程到达一个同步点后再一起继续运行,在其中任意一个线程未达到同步点,其他到达的线程均会被阻塞。
CyclicBarrier是一种同步机制允许一组线程相互等待,等到所有线程都到达一个屏障点才退出await方法,它没有直接实现AQS而是借助ReentrantLock来实现的同步机制。它是可循环使用的,而CountDownLatch是一次性的,另外它体现的语义也跟CountDownLatch不同,CountDownLatch减少计数到达条件采用的是release方式,而CyclicBarrier走向屏障点(await)采用的是Acquire方式,Acquire是会阻塞的,这也实现了CyclicBarrier的另外一个特点,只要有一个线程中断那么屏障点就被打破,所有线程都将被唤醒(CyclicBarrier自己负责这部分实现,不是由AQS调度的),这样也避免了因为一个线程中断引起永远不能到达屏障点而导致其他线程一直等待。屏障点被打破的CyclicBarrier将不可再使用(会抛出BrokenBarrierException)除非执行reset操作。
CyclicBarrier源码分析
- 构造方法
CyclicBarrier提供两个构造方法CyclicBarrier(int parties)
和CyclicBarrier(int parties, Runnable barrierAction)
:CyclicBarrier构造方法CyclicBarrier(int parties)
默认构造方法,参数表示拦截的线程数量。CyclicBarrier(int parties, Runnable barrierAction)
由于线程之前的调度是由CPU决定的,所以默认的构造方法无法设置线程执行优先级,CyclicBarrier提供一个更高级的构造函数CyclicBarrier(int parties, Runnable barrierAction)
,用于在线程到达同步点时,优先执行线程barrierAction,这样可以更加方便的处理一些负责的业务场景。
创建CyclicBarrier后,每个线程调用await方法告诉CyclicBarrier自己已经到达同步点,然后当前线程被阻塞。接下来我们来看看await方法的具体实现。
await实现
CyclicBarrier同样提供带超时时间的await和不带超时时间的await:await实现整个await方法的核心是dowait方法的调用,我们来看看dowait的具体实现。
dowait实现
在dowait的前段部分,主要完成了当所有线程都到达同步点(barrier)时,唤醒所有的等待线程,一起往下继续运行,可根据参数barrierAction决定优先执行的线程。
dowait实现前半部分在dowait的实现后半部分,主要实现了线程未到达同步点(barrier)时,线程进入Condition自旋等待,直到等待超时或者所有线程都到达barrier时被唤醒。
dowait实现后半部分在整个dowait:
- 使用ReentrantLock保证每一次操作线程安全;
- 线程等待/唤醒使用Lock配合Condition来实现;
- 线程被唤醒的条件:等待超时或者所有线程都到达barrier。
到这里为止,CyclicBarrier的重要实现源码分析就结束了,接下来还是照样给出一个具体的使用案例,方便掌握CyclicBarrier的具体用法。
CyclicBarrier使用案例
需求:多线程计算数据,merge计算结果。
代码实现:

运行结果:

CyclicBarrier和CountDownLatch都可以实现线程等待,那么它俩之间的区别是什么呢?
CyclicBarrier和CountDownLatch的区别
看了各种资料和书,大家一致的意见都是CountDownLatch是计数器,只能使用一次,而CyclicBarrier的计数器提供reset功能,可以多次使用。但是我不那么认为它们之间的区别仅仅就是这么简单的一点。我们来从jdk作者设计的目的来看,javadoc是这么描述它们的:
CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
从javadoc的描述可以得出:
- CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行;
- CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。
对于CountDownLatch来说,重点是“一个线程(多个线程)等待”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须等待。
CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。
链接:https://www.jianshu.com/p/bce9f156080f
循环屏障CyclicBarrier以及和CountDownLatch的区别的更多相关文章
- Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier
Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...
- java CyclicBarrier以及和CountDownLatch的区别
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的 ...
- java高并发系列 - 第17天:JUC中的循环栅栏CyclicBarrier常见的6种使用场景及代码示例
这是java高并发系列第17篇. 本文主要内容: 介绍CyclicBarrier 6个示例介绍CyclicBarrier的使用 对比CyclicBarrier和CountDownLatch Cycli ...
- CyclicBarrier循环屏障相关
简介 CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会 ...
- 多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier
1.倒计时器CountDownLatch CountDownLatch是一个多线程控制工具类.通常用来控制线程等待,它可以让一个线程一直等待知道计时结束才开始执行 构造函数: public Count ...
- Java并发工具类之同步屏障CyclicBarrier
CyclicBarrier的字面意思是可以循环使用的Barrier,它要做的事情是让一个线程到达一个Barrier的时候被阻塞,直到最后一个线程到达Barrier,屏障才会放开,所有被Barrier拦 ...
- 并发工具类(二)同步屏障CyclicBarrier
前言 JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch.CyclicBarrier.Semphore.Exchanger.Ph ...
- Java并发工具类(二):同步屏障CyclicBarrier
作用 CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point),才继续执行. 简介 CyclicBarrier 的字面意 ...
- 高级同步器:同步屏障CyclicBarrier
引自:http://ifeve.com/concurrency-cyclicbarrier/ 简介 CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的 ...
随机推荐
- Sub-Processes and Call Activities
https://www.activiti.org/userguide/#bpmnCallActivity http://www.flowable.org/docs/userguide/index.ht ...
- 使用 idHTTP 获取 UTF-8 编码的中文网页
uses IdHTTP; const Url = 'http://del.cnblogs.com'; procedure TForm1.Button1Click(Sender: TObject); v ...
- java基础知识点罗列
1:Java泛型 2:clone Java中的深拷贝(深复制)和浅拷贝(浅复制) Java中对Clone的理解 序列化和反序列化的概念 3:Java中有关Null的9件事
- VMMAP的简单使用
1. dotnet.exe 进程占用内存非常疯狂.. 开发同事 提供了一个工具进行简单分析 vmmap.exe 执行了 Ctrl+E 之后 发现将 heap 和managed heap 的内容放到了p ...
- Linux 多主机SSH互信操作---noob....
创建虚拟机后-- ssh-keygen 生成公钥和私钥对 -rw------- 1 root root 1679 11月 4 09:18 id_rsa-rw-r--r-- 1 root root 39 ...
- 查询数据SELECT 之单表查询
一.单表查询的语法与关键字的执行优先级""" # 单表查询# 单标查询完整与法:# select distinct(关键字,代表查询的意思,后面跟)字段1,字段2...( ...
- 软件破解入门(暴力破解CrackMe)
---恢复内容开始--- 所谓暴力破解,就是通过修改汇编代码进而控制程序的运行流程,达到不需注册码也能正常使用软件的目的.相对于解出算法进而编写注册机,暴破的技术含量是比较低的.但也正是因为一本05年 ...
- Delphi动态添加菜单
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- servlet生成验证码代码
package forward; import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt ...
- Bootstrap图像
前面的话 图像在网页制作中也是常要用到的元素,本文将详细介绍Bootstrap图像 响应式图片 通过为图片添加 .img-responsive 类可以让图片支持响应式布局.其实质是为图片设置了 max ...