本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。

并发编程系列博客传送门

CyclicBarrier简介

CyclicBarrier也是JDK并发包中提供的一个辅助并发工具类。CyclicBarrier的作用是让一组线程互相等待,直到这组线程中所有的线程

都到达同步点(完成某个动作,体现到API上就是调用CyclicBarrier的await方法),这些线程才会继续往下工作。

在相互等待的线程被释放后,CyclicBarrier可以被循环使用。这个从这个类的名字中的Cyclic就可以看出。

CyclicBarrier的构造函数


public CyclicBarrier(int parties) {
this(parties, null);
} public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}

CyclicBarrier提供了两个构造函数。一个构造函数只是指定相互等待的线程个数,另外一个构造函数指定了互相等待的线程个数,还指定了

栅栏打开之后会触发的动作。

CyclicBarrier的典型用法

下面的代码模拟了一个解析Excel的过程:这个Excel有5个sheet,使用5个线程分别去解析这个5个sheet,等5个线程全部解析完成后打印出解析结果。


public class CyclicBarrierTest { public static void main(String[] args) { Map<String, Integer> mockExcelSheet = new HashMap<>();
mockExcelSheet.put("sheet1", 1);
mockExcelSheet.put("sheet2", 2);
mockExcelSheet.put("sheet3", 3);
mockExcelSheet.put("sheet4", 4);
mockExcelSheet.put("sheet5", 5);
AtomicInteger result = new AtomicInteger(0); CyclicBarrier cyclicBarrier = new CyclicBarrier(5,new SummaryClerker(result));
for (int i = 0; i < 5; i++) {
new Thread(new Worker(cyclicBarrier,mockExcelSheet,result,i+1)).start();
}
} private static class Worker implements Runnable { private CyclicBarrier cyclicBarrier;
private Map<String, Integer> mockExcelSheet;
private AtomicInteger result;
private int threadIndex; public Worker(CyclicBarrier cyclicBarrier,
Map<String, Integer> mockExcelSheet,
AtomicInteger result,
int threadIndex) {
this.cyclicBarrier = cyclicBarrier;
this.mockExcelSheet = mockExcelSheet;
this.result = result;
this.threadIndex = threadIndex;
} @Override
public void run() {
String sheetName = "sheet" + threadIndex;
Integer integer = mockExcelSheet.get(sheetName);
int processData = processData(integer);
result.addAndGet(processData);
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} private int processData(int originalData) {
return originalData * 10;
}
} private static class SummaryClerker implements Runnable {
private AtomicInteger result; public SummaryClerker(AtomicInteger result) {
this.result = result;
} @Override
public void run() {
System.out.println("the final result is:" + result.toString());
}
} }

CountDownLatch的区别

CountDownLatchCyclicBarrier功能类似。下面举个列子来说明下这两个类的主要区别。

区别一:强调的重点不一样

CountDownLatch更加强调一组线程等待另外一组线程。还是那之前的场景举例:

小王和他老婆分别请了他们的同事来家里吃晚饭,一共请了6个同事。他们会一直等到6个同时全都到齐了才开始吃晚饭。

这个场景中,小王和他老婆就是线程组A,他们的6个同事就是线程组B,线程组A的线程会一直await,知道线程组B的6个同事全部到达,调用countDown

CyclicBarrier更加强调一组线程之间的互相等待。

小王和公司户外俱乐部的同事相约去爬佘山。他们相约在景区入口处集合,等全部的人都到齐后再一起去爬山。这个景区入口就是一个同步点(栅栏),所有

同事都到齐后这个栅栏会打开。

区别二:可重用性不一样

CountDownLatch计数归零后就不能重复利用了,但是CyclicBarrier可以reset进行重复利用。

简单总结

CyclicBarrier源代码比较简单,这边就不具体分析源代码了。

总的来说,CyclicBarrier的主要功能是一组线程互相等待,线程全部到达同步点后这些线程才继续往下工作。

实现的原理是:先到达的线程调用Condition的await方法,进入waiting状态。最后一个到达的线程会调用signalAll方法唤醒所有线程继续往下工作。

一个小坑

CyclicBarrier的reset方法有一个小坑需要我们注意下。

在调用reset之后,只会重置已经到达屏障的线程(已经调用await的线程)因此会存在一个问题(下面还是以爬山的列子说明这个问题):

两拨人相约去爬山,每波人20个。第一拨人约定上午9点在景区门口集合,第二波人约定10点左右集合。

第一波人中,19个人在9点左右都到达了景区门口了,但是剩下的一个人因为堵车而没来的及赶到。这19个人就在景区门口一直等这个迟到的同事。突然在等的过程中,有个同事身体不舒服,就提议取消这次活动,所以大家都散了。

但是堵车的那个同事还没到,也没人通知他活动取消了。他匆匆忙忙终于还是在9点40左右到达了,但是现在他已经分不清自己是第一波人还是第二波人了,第二波人也不知道这个人其实是属于第一波人的。所以只要第二波人中来了19个人他们就开始去爬山了。

第二波人中最后一个到达的会一直在那等待其他的19个人,但实际上他们已经去爬山了。

其实这种情况可以给线程设置一个超时时间来解决。在这个场景中的体现就是,每个人只等待30分钟,还没到期就打道回府。

并发工具——CyclicBarrier的更多相关文章

  1. 并发工具CyclicBarrier源码分析及应用

      本文首发于微信公众号[猿灯塔],转载引用请说明出处 今天呢!灯塔君跟大家讲: 并发工具CyclicBarrier源码分析及应用 一.CyclicBarrier简介 1.简介 CyclicBarri ...

  2. 并发工具CyclicBarrier

    想想一下这样一个场景,有多个人需要过河,河上有一条船,船要等待满10个人才过河,过完河后每个人又各自行动. 这里的人相当于线程,注意这里,每个线程运行到一半的时候,它就要等待一个条件,即船满过河的条件 ...

  3. 并发工具类:CountDownLatch、CyclicBarrier、Semaphore

    在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...

  4. java 并发工具类CountDownLatch & CyclicBarrier

    一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...

  5. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

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

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

  7. 多线程学习笔记六之并发工具类CountDownLatch和CyclicBarrier

    目录 简介 CountDownLatch 示例 实现分析 CountDownLatch与Thread.join() CyclicBarrier 实现分析 CountDownLatch和CyclicBa ...

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

    前言   JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch.CyclicBarrier.Semphore.Exchanger.Ph ...

  9. Java并发(十三):并发工具类——同步屏障CyclicBarrier

    先做总结 1.CyclicBarrier 是什么? CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点) ...

随机推荐

  1. SQL 分组内求最大N个或最小N个

    题目描述 表 Employee +----+-------+--------+--------------+ | Id | Name | Salary | DepartmentId | +----+- ...

  2. 记录一些服务端术语和搭建web服务器

    菜单快捷导航 服务端常用术语 搭建web服务器和配置虚拟主机 记录一些服务端方面的常用术语 1.CS架构和BS架构 1.1 CS架构 CS(Client/Server),基于安装包类型的桌面或手机软件 ...

  3. Python-标准模块与第三方模块

    标准模块 python官方自己的模块 os os与os.path os.chdir('desktop')        跳转至指定目录 os.listdir()                    ...

  4. VBScript 打开含有"空格"的路径 (Open Path with Space)

    记录,VBScript 如何打开,含有"空格"的路径.这个问题和常见,却总是忘! 直接上代码了,多说无益. Option Explicit Dim obj Dim path Set ...

  5. Spring中应用的那些设计模式

    设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记,只是一直没有记忆. 今天,我们就设计模式的内在价值做一番探讨,并以spring为例进行讲解,只有领略了其设计的思想理念 ...

  6. Sql练习201908210951

    表结构: create table SalePlan ( PlanId ,) primary key, GoodsId int, PlanPrice decimal(,) ); go create t ...

  7. Unix 下 使用 RVM 管理 Ruby 和 gem

    转载:http://www.ibm.com/developerworks/cn/aix/library/au-aix-manage-ruby/   尽管 Internet Relay Chat.论坛和 ...

  8. SSM项目启动的三种方式

    SSM整合Maven项目的三种启动方式 项目部署如图: 1.从父工程的的tomcat插件中直接启动 2.从web子工程的tomcat插件中启动,(需要先执行父工程的install) 如果没有执行父工程 ...

  9. STM32F103ZET6系统定时器SysTick

    1.系统定时器SysTick的简介 系统定时器SysTick属于内核外设,内嵌在NVIC中.SysTick是一个24位的向下递减的计数器,计数器根据SysTick的时钟源计数,当SysTick的计数器 ...

  10. Pointer Lock API(1/3):Pointer Lock 的总体认识

    前言 指针锁定(Pointer Lock),以前也叫鼠标锁定,提供了基于鼠标随时间的移动(如deltaΔ)的输入方法,不仅仅是视窗区域鼠标的绝对位置.指针锁定让你能够访问原始的鼠标移动,将鼠标事件的目 ...