CyclicBarrier的字面意思是可以循环使用的Barrier,它要做的事情是让一个线程到达一个Barrier的时候被阻塞,直到最后一个线程到达Barrier,屏障才会放开,所有被Barrier拦截的线程才会继续运行。

  CyclicBarrier的默认的构造器是CyclicBarrier(int parties),参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。示例代码如下:

  

public class CyclicBarrierTest {

    private static CyclicBarrier barrier = new CyclicBarrier(2);

    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {

        new Thread(new Runnable() {

            @Override
public void run() {
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.print("thread1");
} }).start(); barrier.await(); System.out.println("mainThread");
}
}

  因为子线程和主线程的调度由CPU决定,每个线程都有可能优先执行,因此会产生两种不同的结果,可能的结果如下:

  mainThread
  thread1

  如果把CyclicBarrier的Barrier的个数由2改为3,则主线程和子线程会永远等待,因为没有第三个线程执行await方法,即没有第三个线程到达屏障,因此之前到达屏障的两个线程都不会继续执行。

  CyclicBarrier还提供了一个高级的构造器,CyclicBarrier(int parties, Runnable barrierAction),用于在线程到达屏障后,优先执行barrierAction线程里面的逻辑。比如有如下的场景,在所有的线程都处理完成后,打印“All Done”,可以参考如下代码:

  

public class CyclicBarrierTest2 {

    private static CyclicBarrier barrier = new CyclicBarrier(2,new DoneThread());

    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {

        new Thread(new Runnable() {

            @Override
public void run() { System.out.println("thread1");
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} }).start(); System.out.println("mainThread");
barrier.await();
} static class DoneThread implements Runnable{ @Override
public void run() {
System.out.println("All Done");
} }
}

  输出结果如下:

mainThread
thread1
All Done

  因此CyclicBarrier常用于处理,多线程计算最后合并计算结果的场景。

CyclicBarrier和CountDownLatch的区别:

  1.CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset方法重置,因此CyclicBarrier可以处理线程计算出错时重复计算的场景。

  2.CyclicBarrier还提供了别的有用的方法,如getNumberWaiting可以获得等待的线程数,isBroken方法可以了解阻塞的线程是否被中断等。

最新文章

  1. 移动UI设计
  2. 字符串反转----将this is good 转化为good is this 输出。
  3. ldap配置记录
  4. 使用jquery-qrcode生成二维码
  5. 一个ubuntu phper的自我修养(ubuntu安装)
  6. resolv.conf
  7. C#实现Excel的导入导出
  8. 决策树之C4.5算法
  9. Form认证导致登陆页面的样式无效和图片不能显示的原因
  10. 一种基于C51单片机的非抢占式的操作系统架构
  11. 【python】自定义函数def funName():
  12. Spring boot(三)整合mybaties+thymeleaf实现基础crud
  13. Java多线程处理某个线程超时的问题
  14. STLINK V2安装使用详解
  15. 最全的maven的pom.xml文件详解
  16. OpenGL开发学习指南二(glfw+glad)
  17. Map Wiki -- proposed by Shuo Ren
  18. 到底该用img还是background-image?
  19. scala 读取文件加下的指定文件
  20. 华为S5300系列交换机V100R006SPH019升级补丁

热门文章

  1. 201621123008 《Java程序设计》第六周实验总结
  2. Codeforces 689C. Mike and Chocolate Thieves 二分
  3. "UX"将会是下一个Buzzword?
  4. vue的过滤器
  5. HRegionServer异常下线问题
  6. 关于对象的 width offsetwidth availWidth scrollHeight
  7. PacBio下机数据如何看?
  8. jQuery 插件使用记录
  9. 657. Judge Route Circle
  10. 2018.09.20 atcoder Building Cubes with AtCoDeer(枚举)