循环屏障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).它要做的 ...
随机推荐
- 如何自定义一个组件loading
使用时需要Vue.use()一下
- ThreadPoolExecutor使用详解
ThreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线 ...
- 关于Windows 2019 antimalware 进程占用CPU 过多的处理方法 关闭windows 病毒防护的方法
0. 客户端打开报错 重启之后 响应速度很慢. 解决办法: 1. 打开组策略 gpedit.msc 2. 选择位置为 3. 查看 进程里面后台程序 antimalware 进程消失 即可
- [CB]2018全球半导体营收4700亿美元 三星继续碾压英特尔
2018全球半导体营收4700亿美元 三星继续碾压英特尔 https://www.cnbeta.com/articles/tech/808833.htm Gartner最新报告显示,2018年全球半导 ...
- Kali2.0的简单使用--开启root用户登录
1. 安装完kali之后 2. 修改/etc/ssh/sshd_conf的文件 将: #PasswordAuthentication no 修改为: PasswordAuthentication ye ...
- scipy线性模块liner(linalg)
#liner import numpy as np from scipy import linalg as lg arr=np.array([[1,1],[0,1]]) matr=np.mat('[1 ...
- js條件結構和循環結構
條件結構: if(語句1) if(語句1)else(語句2) if(語句1)elseif(語句2)else(語句3) switch結構: switch() { case 1: break: case ...
- BZOJ2144跳跳棋——LCA+二分
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- Codeforces Round #426 (Div. 2) A,B,C
A. The Useless Toy 题目链接:http://codeforces.com/contest/834/problem/A 思路: 水题 实现代码: #include<bits/st ...
- MT【213】二次曲线系方程
(2013北大夏令营)函数$y=x^2+ax+b$与坐标轴交于三个不同的点$A,B,C$,已知$\Delta ABC$的外心$P$在$y=x$上,求$a+b$的值. 解:由二次曲线系知识知三角形的外接 ...