• 介绍

  一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

  CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。

  • 主要方法
  •  //设置parties、count及barrierCommand属性。
    CyclicBarrier(int):
    //当await的数量到达了设定的数量后,首先执行该Runnable对象。
    CyclicBarrier(int,Runnable):
    //通知barrier已完成线程
    await():
  • 应用场景

  1:CyclicBarrier 表示大家彼此等待,大家集合好后才开始出发,分散活动后又在i指定地点集合碰面,这就好比整个公司的人员利用周末时间集体郊游一样,先各自从家出发到公司集合后,再同时出发到公园游玩,在指定地点集合后再同时开始就餐。

  代码:

 public class CyclicBarrierTest {
public static void main(String[] args){
ExecutorService pool = Executors.newCachedThreadPool();
final CyclicBarrier cyclicBarrier = new CyclicBarrier(3); for (int i = 0; i < 3; i++) {
Runnable runnable = new Runnable() {
@Override
public void run(){
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达地点一,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"继续出发":"继续等待"));
try {
cyclicBarrier.await();//障碍等待点
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达地点二,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"继续出发":"继续等待"));
try {
cyclicBarrier.await();//障碍等待点
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达地点三,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"人齐了出发":"继续等待"));
try {
cyclicBarrier.await();//障碍等待点
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
pool.execute(runnable);
}
pool.shutdown();
}
}

  执行结果:

 pool-1-thread-3到达地点一,当前等待人数为1继续等待
pool-1-thread-1到达地点一,当前等待人数为2继续等待
pool-1-thread-2到达地点一,当前等待人数为3继续出发
pool-1-thread-1到达地点二,当前等待人数为1继续等待
pool-1-thread-3到达地点二,当前等待人数为2继续等待
pool-1-thread-2到达地点二,当前等待人数为3继续出发
pool-1-thread-3到达地点三,当前等待人数为1继续等待
pool-1-thread-2到达地点三,当前等待人数为2继续等待
pool-1-thread-1到达地点三,当前等待人数为3人齐了出发

  2:在某种需求中,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择CyclicBarrier了。

  代码:

 public class CyclicBarrierTest1 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();
CyclicBarrier barrier = new CyclicBarrier(5, new mainTask());
for (int i = 0; i < 5; i++) {
subTask subTask = new subTask(barrier);
threadPool.execute(subTask);
}
threadPool.shutdown();
}
} class subTask implements Runnable{
private CyclicBarrier barrier; public subTask(CyclicBarrier barrier) {
super();
this.barrier = barrier;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在执行");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行完毕,等待其他结果");
try {
barrier.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
class mainTask implements Runnable{ @Override
public void run() {
System.out.println("总任务执行完毕");
} }

  执行结果:

 pool-1-thread-2正在执行
pool-1-thread-3正在执行
pool-1-thread-1正在执行
pool-1-thread-4正在执行
pool-1-thread-5正在执行
pool-1-thread-2执行完毕,等待其他结果
pool-1-thread-5执行完毕,等待其他结果
pool-1-thread-1执行完毕,等待其他结果
pool-1-thread-4执行完毕,等待其他结果
pool-1-thread-3执行完毕,等待其他结果
总任务执行完毕

  另外,CyclicBarrier是可以重用的,它可以在使用完后继续使用,这就是Cyclic(循环)的意思。

java多线程-CyclicBarrier的更多相关文章

  1. 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例

    java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...

  2. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

  3. Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier

    Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...

  4. JAVA多线程提高十:同步工具CyclicBarrier与CountDownLatch

    今天继续学习其它的同步工具:CyclicBarrier与CountDownLatch 一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ...

  5. java多线程10:并发工具类CountDownLatch、CyclicBarrier和Semaphore

    在JDK的并发包(java.util.concurrent下)中给开发者提供了几个非常有用的并发工具类,让用户不需要再去关心如何在并发场景下写出同时兼顾线程安全性与高效率的代码. 本文分别介绍Coun ...

  6. 40个Java多线程问题总结

    前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...

  7. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  8. Java多线程系列--“JUC锁”01之 框架

    本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...

  9. Java多线程系列目录(共43篇)

    最近,在研究Java多线程的内容目录,将其内容逐步整理并发布. (一) 基础篇 01. Java多线程系列--“基础篇”01之 基本概念 02. Java多线程系列--“基础篇”02之 常用的实现多线 ...

随机推荐

  1. 【对比分析八】null和undefined的区别

    (1).  null是一个表示"无"的对象,转为数值时为0  undefined是一个表示"无"的原始值,转为数值时为NaN (2).  当声明的变量还未被初始 ...

  2. LeetCode题解-----Median of Two Sorted Arrays

    题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of t ...

  3. 【温故而知新-Javascript】使用事件

    1. 使用简单事件处理器 可以用几种不同的方式处理事件.最直接的方式是用事件属性创建一个简单事件处理器(simple event handler).元素为它们支持的每一种事件都定义了一个事件属性.举个 ...

  4. 【问题&解决】解决 Android SDK下载和更新失败“Connection to https://dl-ssl.google.com refused”的问题

    缘由: 更新sdk,遇到了更新下载失败问题: Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xmlFetche ...

  5. html5 实现video标签的自定义播放进度条

    现在随着html5的渐热,越来越多的web开发者都开始选择使用html5写出一些比较好的web应用. html代码: <!DOCTYPE html> <html lang=" ...

  6. Jenkins学习七:Jenkins的授权和访问控制

    默认的Jenkins不包含任何的安全检查,任何人可以修改Jenkins设置,job和启动build等.显然地在大规模的公司需要多个部门一起协调工作的时候,没有任何安全检查会带来很多的问题. 在系统管理 ...

  7. java 21-11 数据输入、输出流和内存操作流

    IO数据流: 可以读写基本数据类型的数据 数据输入流:DataInputStream DataInputStream(InputStream in)   数据输出流:DataOutputStream ...

  8. maya获取邻接顶点的一个问题

    maya网格数据结构允许"非流形"的存在,于是,这种数据结构无法按顺序给出一个点的邻接顶点. 于是,MItMeshVertex::getConnectedVertices函数返回的 ...

  9. 设置linux账号的有效时间

    在linux系统中,默认创建的用户的有效期限都是永久的,但有时候,我们需要对某些用户的有效期限做个限定!比如:公司给客户开的ftp账号,用于客户下载新闻稿件的.这个账号是有时间限制的,因为是付费的.合 ...

  10. Javascript的变量与delete操作符

    原文:http://charlee.li/javascript-variables-and-delete-operator.html 刚刚看到一篇好文(原文链接), 对Javascript中的dele ...