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

  CyclicBarrier类似于CountDownLatch也是个计数器, 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。

构造方法摘要
CyclicBarrier(int parties)
          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行
方法摘要
int await()
          在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
int await(long timeout, TimeUnit unit)
          在所有参与者都已经在此屏障上调用 await 方法之前,将一直等待。
int getNumberWaiting()
          返回当前在屏障处等待的参与者数目。
int getParties()
          返回要求启动此 barrier 的参与者数目。
boolean isBroken()
          查询此屏障是否处于损坏状态。
void reset()
          将屏障重置为其初始状态。
 package com.thread;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; public class CyclicBarrierTest { public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点
for(int i=0;i<3;i++){
Runnable runnable = new Runnable(){
public void run(){
try {
Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行 Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点2,当前已有2个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候

  如果在构造CyclicBarrier对象的时候传了一个Runnable对象进去,则每次到达公共屏障点的时候都最先执行这个传进去的Runnable,然后再执行处于等待的Runnable。如果把上面的例子改成下面这样:

 package com.thread;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; public class CyclicBarrierTest { public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
//final CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点
final CyclicBarrier cb = new CyclicBarrier(3,new Runnable(){
@Override
public void run() {
System.out.println("********我最先执行***********");
}
});
for(int i=0;i<3;i++){
Runnable runnable = new Runnable(){
public void run(){
try {
Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行 Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await(); //这里CyclicBarrier对象又可以重用
Thread.sleep((long)(Math.random()*10000));
System.out.println("线程" + Thread.currentThread().getName() +
"即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}

则结果如下:

线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
********我最先执行***********
线程pool-1-thread-1即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已经到达,正在等候
********我最先执行***********
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
********我最先执行***********

CyclicBarrier的用法的更多相关文章

  1. Java Concurrency - 浅析 CyclicBarrier 的用法

    The Java concurrency API provides a synchronizing utility that allows the synchronization of two or ...

  2. CountDownLatch和CyclicBarrier 的用法

    CountDownLatch是减计数方式,计数==0时释放所有等待的线程:CyclicBarrier是加计数方式,计数达到构造方法中参数指定的值时释放所有等待的线程.CountDownLatch当计数 ...

  3. Java多线程之新类库中的构件CyclicBarrier

    1.类说明: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 Cycl ...

  4. 戏说java多线程之CyclicBarrier(循环栅栏)的CyclicBarrier(int parties)构造方法

    CyclicBarrier是JDK 1.5 concurrent包出现的一个用于解决多条线程阻塞,当达到一定条件时一起放行的一个类.我们先来看这样一个简单的需求. 现在我有一个写入数据的类,继承Run ...

  5. CountDownLatch/CyclicBarrie用法记录

    在jdk1.5中,java提供了很多工具类帮助我们进行并发编程,其中就有CountDownLatch和CyclicBarrie 1.CountDownLatch的用法 CountDownLatch 位 ...

  6. JDK5.0 特性线程 同步装置之CountDownLatch 同步装置之CyclicBarrier 线程 BlockingQueue

    来自:http://www.cnblogs.com/taven/category/475298.html import java.util.concurrent.CountDownLatch; imp ...

  7. java高级---->Thread之CyclicBarrier的使用

    CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).今天我们就学习一下CyclicBarrier的用法. Cycl ...

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

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

  9. 25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger

    1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join ...

随机推荐

  1. Linux学习18-gitlab新建项目提交代码

    前言 gitlab前面已经搭建好了,如果我们想用把代码上传到gitlab仓库上的话,先要新建一个项目仓库.然后本地安装git环境,就可以提交了 root用户 gitlab首次在浏览器上打开web页面, ...

  2. Loader的初步学习笔记

    Loader是一个异步加载数据的类,它和AsyncTask有类似也有不同,今天我们就先来学习下它.由于是对比学习,所以我们先来复习下AsyncTask的使用和特点. 一.AsyncTask 参考自:h ...

  3. error “Device supports x86, but APK only supports armeabi-v7a”

    checkout the build.gradle from module:app. It turns out that there's a such config: ndk { abiFilters ...

  4. SQL Server 函数 LEN 与 DATALENGTH的区别

    http://blog.csdn.net/Hello_World_wusu/article/details/4667452 DATALENGTH()函数返回一个用于对值进行管理的字节数,这有助于揭示不 ...

  5. go语言之进阶篇方法的继承

    1.方法的继承 示例: package main import "fmt" type Person struct { name string //名字 sex byte //性别, ...

  6. 前端性能优化:配置ETag

    什么是ETag? 实体标签(EntityTag)是唯一标识了一个组件的一个特定版本的字符串,是web服务器用于确认缓存组件的有效性的一种机制,通常可以使用组件的某些属性来构造它. 条件GET请求 浏览 ...

  7. 关于android SDK安装Failed to fetch URL 一点思考

    最近SDK出问题了,然后在google下载了一个android-sdk-windows.rar,然后点击SDK Manager,结果一直不能刷新API Level,然后就开始在网上找了好多资料,解决这 ...

  8. Gradle - Manifest

    Manifest DSL提供了配置以下Manifest条目的功能: minSdkVersion / targetSdkVersion / versionCode / versionName / app ...

  9. NLP领域的ImageNet时代到来:词嵌入「已死」,语言模型当立

    http://3g.163.com/all/article/DM995J240511AQHO.html 选自the Gradient 作者:Sebastian Ruder 机器之心编译 计算机视觉领域 ...

  10. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十二)Spark Streaming接收流数据及使用窗口函数

    官网文档:<http://spark.apache.org/docs/latest/streaming-programming-guide.html#a-quick-example> Sp ...