CyclicBarrier循环的栅栏。使用上,与CountDownLatch类似,也不太一样。这两个类都是用来解决线程同步问题的。同步问题说的通俗一点就是线程间通信。

CountDownLatch,是主线程等待所有子线程结束任务

CyclicBarrier,是多个子线程互相等待

下面看看CyclicBarrier的源码实现

public CyclicBarrier(int parties, Runnable barrierAction) {if (parties <= 0) throw new IllegalArgumentException();this.parties = parties;// 需要汇集的线程的个数,是一个不变量。用来做重置this.count = parties;// 需要汇集的线程的个数,用来做计数this.barrierCommand = barrierAction;// 线程汇集到一点后的回调异步任务
}// parties,需要汇集的线程的个数
public CyclicBarrier(int parties) {this(parties, null);
}

两种构造方式,一种是带有Runnable回调的,一种没有。带有回调是指当多个子线程汇集到一点后,可以执行一个异步任务,后面会分析到。

private static class Generation {boolean broken = false;// 栅栏是否被破坏的标识
}
private final ReentrantLock lock = new ReentrantLock();// 可重入锁,一定是可重入的。
private final Condition trip = lock.newCondition();// 条件等待期
private final int parties;// 需要汇集的线程的个数,是一个不变量。用来做重置
private final Runnable barrierCommand;// 线程汇集到一点后的回调异步任务
private Generation generation = new Generation();// 每个新的栅栏会new这么一个对象
private int count;// 需要汇集的线程的个数,用来做计数

上面是一堆成员变量,各自的用途已经在注释中写明。下面看跟API相关的几个方法。await

public int await() throws InterruptedException, BrokenBarrierException {try {return dowait(false, 0L);} catch (TimeoutException toe) {throw new Error(toe); // cannot happen}
}
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException {return dowait(true, unit.toNanos(timeout));
}

无论是限时等待还是不限时等待,都会去调用dowait方法。重点在这个dowait方法。

private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException {final ReentrantLock lock = this.lock;lock.lock();// 线程进来先上锁,所以这边用的一定是可重入锁try {final Generation g = generation;// 把generation暂时保存一下,后面比对用if (g.broken)// 如果栅栏已经被破坏,则抛出已经被破坏的异常throw new BrokenBarrierException();if (Thread.interrupted()) {// 如果检测到当前线程被打断,则把整个栅栏都通知破坏了。因为其他线程再等待也等不来。breakBarrier();throw new InterruptedException();}int index = --count;// 来一个线程,计数器-1if (index == 0) {  // 如果计数器减到0,说明所有线程都汇集到某一点了。boolean ranAction = false;try {final Runnable command = barrierCommand;if (command != null)command.run();// 运行回调异步任务ranAction = true;// 运行成功nextGeneration();// 生成一个新的栅栏return 0;} finally {if (!ranAction)// 如果回调任务运行失败,则破坏栅栏breakBarrier();}}// loop until tripped, broken, interrupted, or timed outfor (;;) {// 死循环,自旋,准备进入条件等待。try {if (!timed)trip.await();// 不限等待时间的等待else if (nanos > 0L)nanos = trip.awaitNanos(nanos);// 限时间等待} catch (InterruptedException ie) {if (g == generation && ! g.broken) {breakBarrier();// 线程被打断,并且栅栏还没有被破坏,则去破坏栅栏throw ie;} else {// 其他线程破坏了栅栏Thread.currentThread().interrupt();// 自我中断}}if (g.broken)// 再看看栅栏是否被破坏throw new BrokenBarrierException();if (g != generation)// 如果generation刷新说明成功了。返回即可return index;if (timed && nanos <= 0L) {// 超时情况,破坏栅栏breakBarrier();throw new TimeoutException();}}} finally {lock.unlock();}
}

CyclicBarrier原理分析相关推荐

  1. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析

    1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...

  2. java并发包线程池原理分析锁的深度化

    java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素 ...

  3. java signature 性能_Java常见bean mapper的性能及原理分析

    背景 在分层的代码架构中,层与层之间的对象避免不了要做很多转换.赋值等操作,这些操作重复且繁琐,于是乎催生出很多工具来优雅,高效地完成这个操作,有BeanUtils.BeanCopier.Dozer. ...

  4. Select函数实现原理分析

    转载自 http://blog.chinaunix.net/uid-20643761-id-1594860.html select需要驱动程序的支持,驱动程序实现fops内的poll函数.select ...

  5. spring ioc原理分析

    spring ioc原理分析 spring ioc 的概念 简单工厂方法 spirng ioc实现原理 spring ioc的概念 ioc: 控制反转 将对象的创建由spring管理.比如,我们以前用 ...

  6. 一次 SQL 查询优化原理分析(900W+ 数据,从 17s 到 300ms)

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:Muscleape jianshu.com/p/0768eb ...

  7. 原理分析_变色近视眼镜原理分析

    随着眼镜的发展,眼镜的外型变得越来越好看,并且眼镜的颜色也变得多姿多彩,让佩戴眼镜的你变得越来越时尚.变色近视眼镜就是由此产生的新型眼镜.变色镜可以随着阳光的强弱变换不同的色彩. 变色眼镜的原理分析 ...

  8. jieba分词_从语言模型原理分析如何jieba更细粒度的分词

    jieba分词是作中文分词常用的一种工具,之前也记录过源码及原理学习.但有的时候发现分词的结果并不是自己最想要的.比如分词"重庆邮电大学",使用精确模式+HMM分词结果是[&quo ...

  9. EJB调用原理分析 (飞茂EJB)

    EJB调用原理分析 EJB调用原理分析 作者:robbin (MSN:robbin_fan AT hotmail DOT com) 版权声明:本文严禁转载,如有转载请求,请和作者联系 一个远程对象至少 ...

最新文章

  1. 青海高考成绩查询日期2021,2021年青海高考成绩什么时候出来 公布时间
  2. 升级Hbase,解决bug问题
  3. 卷积神经网络如何解释和预测图像
  4. python接口测试jason_Python 接口测试之Json数据文件操作
  5. Linux下XPath对xml解析
  6. 每日面试之Java集合
  7. 基础强化:深入理解JVM中的方法调用
  8. esri-leaflet入门教程(4)-加载各类图层
  9. web操作日志丢失_日志异步落库,你了解不
  10. android 教程实例系列
  11. 1.STC15W408AS单片机硬件资源
  12. python表示倍数的英语句型_5种倍数表达法句型
  13. 什么是存储过程?为什么要写存储过程
  14. youtube打开显示服务器更新,youtube-dl更新出错解决办法
  15. ORACLE SQL常用用法
  16. centos7.x 搭建php运行环境
  17. 《策略驱动型数据中心——ACI技术详解》一1.3 数据中心设计
  18. python摄像头动作捕捉_OpenMMD:没有专业摄像设备也能动作捕捉!K帧动作设计苦手的福音~...
  19. 网络游戏服务器架构流程
  20. 设置背景透明 html5,webview的背景如何设置成透明的?

热门文章

  1. linux压缩文件夹怎么看进度,dd进度的查看方法
  2. pycharm-社区版启动django项目的服务
  3. Linux 上如何让任意普通用户执行拥有root权限的特定脚本或者程序
  4. 简单工厂模式(代码实现)
  5. 联想460A笔记本ubuntu下关闭独立显卡
  6. creatFolder
  7. Maven打jar包包含源代码
  8. 计算机网络怎么知道起始序号,怎么知道自己电脑上操作系统的序列号?
  9. 漂亮的蓝色系网站设计欣赏2
  10. aspose将word文档转为html内容