先做总结

1、CyclicBarrier 是什么?

CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到要求的线程到达都屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。

2、CyclicBarrier 实现原理:

  private static class Generation { // 内部类,当有parties个线程到达barrier,就会更新换代
    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(); // 当有parties个线程到达barrier,就会更新换代
  private int count; // 记录当前线程数量

(1)构造CyclicBarrier 时设置等待线程总数量parties 和 达到等待线程数量后执行的线程barrierCommand;

(2)线程中调用CyclicBarrier 的await() 方法时,将线程park() 并放入trip 的条件队列中,记录当前阻塞线程数 count;

(3)线程中调用CyclicBarrier 的await() 方法时,发现当前阻塞线程数 count达到了 构造时设置的总线程数,做如下操作:

    ① trip.signalAll()唤醒所有线程

    ② 重置count(从而实现同一个CyclicBarrier 对象可以循环使用)

    ③ 执行barrierCommand线程

一、应用举例

public class CyclicBarrierTest {
private static CyclicBarrier cyclicBarrier; static class CyclicBarrierThread extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + "到了");
try {
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
cyclicBarrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.out.println("人到齐了,开会吧....");
}
}); for (int i = 0; i < 5; i++) {
new CyclicBarrierThread().start();
}
}
}

二、类结构

public class CyclicBarrier {
private static class Generation { // 内部类,当有parties个线程到达barrier,就会更新换代
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(); // 当有parties个线程到达barrier,就会更新换代
private int count; // 记录当前线程数量 public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
} public CyclicBarrier(int parties) {
this(parties, null);
}
}

三、原理解析

    public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen
}
} private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException(); if (Thread.interrupted()) {
breakBarrier(); // 代失效,唤醒所有线程
throw new InterruptedException();
} int index = --count; // 计数
if (index == 0) { // 达到要求数量
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run(); // 达到等待线程数量后执行barrierCommand
ranAction = true;
nextGeneration(); // 唤醒本代所有线程,生成新一代,重置count
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
} // 线程数量未达到要求数量,将线程挂起等待
for (;;) {
try {
if (!timed)
trip.await(); // 将线程加入condition队列挂起
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)
return index;
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
} // 代失效,唤醒所有线程
private void breakBarrier() {
generation.broken = true;
count = parties;
trip.signalAll();
} // 唤醒本代所有线程,生成新一代,重置count
private void nextGeneration() {
trip.signalAll();
count = parties;
generation = new Generation();
}

并发工具类(二)同步屏障CyclicBarrier

【死磕Java并发】—–J.U.C之并发工具类:CyclicBarrier

Java并发(十三):并发工具类——同步屏障CyclicBarrier的更多相关文章

  1. Java中的并发工具类(CountDownLatch、CyclicBarrier、Semaphore、Exchanger)

    在JDK的并发包里提供了很多有意思的并发工具类.CountDownLatch.CyclicBarrier和Semaphore 工具类提供了一种并发流程控制的手段,Exchanger 工具类则提供了在线 ...

  2. Redis 工具类 java 实现的redis 工具类

    最近了解了一下非关系型数据库 redis 会使用简单的命令 在自己本地电脑 使用时必须先启动服务器端 在启动客户端 redis 简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内 ...

  3. Rhino+envjs-1.2.js 在java运行网站js 工具类

    java爬虫遇到个页面加密的东西,找了些资料学习学习 做了个java运行js的工具类,希望对大家有用,其中用到client(获取js)可以自行换成自己的client.主要是用了 Rhino就是Java ...

  4. java中常用的工具类(一)

    我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...

  5. Java学习-041-颜色工具类(RGB,HEX)

    在日常的网页开发中,经常需要进行颜色数值获取.转换,例如获取红色,获取蓝色,获取绿色,RGB转十六进制颜色,十六进制颜色转RGB等,因而在学习过程中,写了一个小工具类,仅供各位小主参考! 多不闲言,直 ...

  6. JAVA中封装JSONUtils工具类及使用

    在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...

  7. JAVA自动生成正则表达式工具类

    经过很久的努力,终于完成了JAVA自动生成正则表达式工具类.还记得之前需要正则,老是从网上找吗?找了想修改也不会修改.现在不用再为此烦恼了,使用此生成类轻松搞定所有正则表达式.赶快在同事面前炫一下吧. ...

  8. java 二进制数字符串转换工具类

    java 二进制数字符串转换工具类 将二进制转换成八进制 将二进制转换成十进制 将二进制转换成十六进制 将十进制转换成二进制 package com.iteye.injavawetrust.ad; i ...

  9. Java学习-049-正则工具类

    自去年九月份决定再次入学和职业资格进阶,开始备战二者考试至今,以及当下进行中的职称申请,犹如孤独的狼,不断前行在路上,而今凡凡总总的已历8月... 不感慨了,如下为一园友需要的正则工具类,直接上码: ...

随机推荐

  1. 【leetcode 简单】第三十一题 买卖股票的最佳时机

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票. 示例 ...

  2. solr笔记之安装部署到tomcat

    1. 下载 solr 去官网下载,下载的时候选清华的镜像源,这个页面:https://mirrors.tuna.tsinghua.edu.cn/apache/lucene/solr/7.1.0/ 在/ ...

  3. 原 jQuery中document的ready和load事件的区别?

    概述: 大家在工作中用jQuery的时候一定会在使用之前这样:   1 2 3 4 5 6 7 8 //document ready $(document).ready(function(){     ...

  4. 64_m3

    molequeue-doc-0.8.0-2.20161222giteb397e.fc26.no..> 05-Apr-2017 10:04 451570 molequeue-libs-0.8.0- ...

  5. 用C++写程序的一些感悟

    前言 近期使用C++有了一些心得很感悟,这里整理一下. 心得1 如果只会使用LabVIEW写程序,还想要进一步深入程序设计,一定要学习一门文本语言. 什么是会用LabVIEW 会用是个比较笼统的概念. ...

  6. falsk注册etcd

    部署web服务集群时,我们希望能动态调整集群大小.当一个新的节点启动时,可以将自己的信息注册给master, 让master把它加入到集群里, 关闭之后也可以把自己从集群中删除.我这里使用的是flas ...

  7. [ python ] 全局和局部作用域变量的引用

    全局与局部变量的引用 (a)locals(b)globals 这里还需要在补充2个关键字一起比较学习,关键字:(c)nonlocal(d)global locals 和 globals locals: ...

  8. svm和svr区别--摘自其它博客

    学习笔记:SVM柔性边界的补充和SVR(支持向量回归) 作者 小刺猬yyx 关注 2016.08.06 10:31* 字数 1608 阅读 421评论 0喜欢 2 上一个笔记对于SVM不能完美分类的情 ...

  9. 百度2017春招<度度熊回家问题>

    题目: 一个数轴上共有N个点,第一个点的坐标是度度熊现在位置,第N-1个点是度度熊的家.现在他需要依次的从0号坐标走到N-1号坐标.但是除了0号坐标和N-1号坐标,他可以在其余的N-2个坐标中选出一个 ...

  10. ~Delphi const 杂谈~

    来自:http://www.cnblogs.com/tibetwolf/articles/1785744.html ------------------------------------------ ...