CyclicBarrier介绍 (一)
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。 
 
CyclicBarrier (周期障碍)类可以帮助同步,它允许一组线程等待整个线程组到达公共屏障点。CyclicBarrier 是使用整型变量构造的,其确定组中的线程数。当一个线程到达屏障时(通过调用 CyclicBarrier.await()),它会被阻塞,直到所有线程都到达屏障,然后在该点允许所有线程继续执行。与CountDownLatch不同的是,CyclicBarrier 所有公共线程都到达后,可以继续执行下一个目标点,而CountDownLatch第一次到达指定点后,也就是记数器减制零,就无法再次执行下一目标工作。
 

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

实例分析
我们需要统计全国的业务数据。其中各省的数据库是独立的,也就是说按省分库。并且统计的数据量很大,统计过程也比较慢。为了提高性能,快速计算。我们采取并发的方式,多个线程同时计算各省数据,最后再汇总统计。在这里CyclicBarrier就非常有用。看代码:

主要类:

Java代码 
  1. /**  
  2.  * 各省数据独立,分库存偖。为了提高计算性能,统计时采用每个省开一个线程先计算单省结果,最后汇总。  
  3.  *   
  4.  * @author guangbo email:weigbo@163.com  
  5.  *   
  6.  */  
  7. public class Total {   
  8.   
  9.     // private ConcurrentHashMap result = new ConcurrentHashMap();   
  10.   
  11.     public static void main(String[] args) {   
  12.         TotalService totalService = new TotalServiceImpl();   
  13.         CyclicBarrier barrier = ,   
  14.                 new TotalTask(totalService));   
  15.   
  16.         // 实际系统是查出所有省编码code的列表,然后循环,每个code生成一个线程。   
  17.         new BillTask(new BillServiceImpl(), barrier, "北京").start();   
  18.         new BillTask(new BillServiceImpl(), barrier, "上海").start();   
  19.         new BillTask(new BillServiceImpl(), barrier, "广西").start();   
  20.         new BillTask(new BillServiceImpl(), barrier, "四川").start();   
  21.         new BillTask(new BillServiceImpl(), barrier, "黑龙江").start();   
  22.   
  23.     }   
  24. }   
  25.   
  26. /**  
  27.  * 主任务:汇总任务  
  28.  */  
  29. class TotalTask implements Runnable {   
  30.     private TotalService totalService;   
  31.   
  32.     TotalTask(TotalService totalService) {   
  33.         this.totalService = totalService;   
  34.     }   
  35.   
  36.     public void run() {   
  37.         // 读取内存中各省的数据汇总,过程略。   
  38.         totalService.count();   
  39.         System.out.println("=======================================");   
  40.         System.out.println("开始全国汇总");   
  41.     }   
  42. }   
  43.   
  44. /**  
  45.  * 子任务:计费任务  
  46.  */  
  47. class BillTask extends Thread {   
  48.     // 计费服务   
  49.     private BillService billService;   
  50.     private CyclicBarrier barrier;   
  51.     // 代码,按省代码分类,各省数据库独立。   
  52.     private String code;   
  53.   
  54.     BillTask(BillService billService, CyclicBarrier barrier, String code) {   
  55.         this.billService = billService;   
  56.         this.barrier = barrier;   
  57.         this.code = code;   
  58.     }   
  59.   
  60.     public void run() {   
  61.         System.out.println("开始计算--" + code + "省--数据!");   
  62.         billService.bill(code);   
  63.         // 把bill方法结果存入内存,如ConcurrentHashMap,vector等,代码略   
  64.         System.out.println(code + "省已经计算完成,并通知汇总Service!");   
  65.         try {   
  66.             // 通知barrier已经完成   
  67.             barrier.await();   
  68.         } catch (InterruptedException e) {   
  69.             e.printStackTrace();   
  70.         } catch (BrokenBarrierException e) {   
  71.             e.printStackTrace();   
  72.         }   
  73.     }   
  74.   
  75. }  

结果:
开始计算--北京省--数据!
开始计算--上海省--数据!
北京省已经计算完成,并通知汇总Service!
开始计算--四川省--数据!
四川省已经计算完成,并通知汇总Service!
上海省已经计算完成,并通知汇总Service!
开始计算--广西省--数据!
广西省已经计算完成,并通知汇总Service!
开始计算--黑龙江省--数据!
黑龙江省已经计算完成,并通知汇总Service!
=======================================
开始全国汇总
CyclicBarrier介绍 (二)

张孝祥视频学习笔记:

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

iimport java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierTest {
 public static void main(String [] args){
  ExecutorService service=Executors.newCachedThreadPool();
  final CyclicBarrier cb= new CyclicBarrier(3);  //三个线程同时到达
  forint 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()+1)+"个已到达"+
        (cb.getNumberWaiting()==2? "都到齐了,继续走啊" :"正在等候" ));
      try {
       cb.await();
      } catch (BrokenBarrierException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      Thread.sleep((long)(Math.random()*10000));
      System. out.println("线程" +Thread.currentThread ().getName()+
        "即将到达集合地点2,当前已有" +(cb.getNumberWaiting()+1)+"个已到达"+
        (cb.getNumberWaiting()==2? "都到齐了,继续走啊" :"正在等候" ));
      try {
       cb.await();
      } catch (BrokenBarrierException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      Thread.sleep((long)(Math.random()*10000));
      System.out.println("线程" +Thread.currentThread ().getName()+
        "即将到达集合地点3,当前已有" +(cb.getNumberWaiting()+1)+"个已到达"+
        (cb.getNumberWaiting()==2? "都到齐了,继续走啊" :"正在等候" ));
      try {
       cb.await();
      } catch (BrokenBarrierException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
   };
   service.execute(runnable);
  }
  service.shutdown();
 }
}

运行结果:

线程pool-1-thread-3即将到达集合地点1,当前已有1个已到达正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已到达正在等候
线程pool-1-thread-1即将到达集合地点1,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-1即将到达集合地点2,当前已有1个已到达正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已到达正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-2即将到达集合地点3,当前已有1个已到达正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有2个已到达正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有3个已到达都到齐了,继续走啊

CyclicBarrier和CountDownLatch介绍的更多相关文章

  1. JDK源码分析之concurrent包(四) -- CyclicBarrier与CountDownLatch

    上一篇我们主要通过ExecutorCompletionService与FutureTask类的源码,对Future模型体系的原理做了了解,本篇开始解读concurrent包中的工具类的源码.首先来看两 ...

  2. Android进阶——多线程系列之Semaphore、CyclicBarrier、CountDownLatch

    今天向大家介绍的是多线程开发中的一些辅助类,他们的作用无非就是帮助我们让多个线程按照我们想要的执行顺序来执行.如果我们按照文字来理解Semaphore.CyclicBarrier.CountDownL ...

  3. CyclicBarrier和CountDownLatch的差别

    CyclicBarrier和CountDownLatch都用多个线程之间的同步,共同点:同时有N个线程在 CyclicBarrier(CountDownLatch) 等待上等待时,CyclicBarr ...

  4. Java并发之CyclicBarrier、CountDownLatch、Phaser

    在Java多线程编程中,经常会需要我们控制并发流程,等其他线程执行完毕,或者分阶段执行.Java在1.5的juc中引入了CountDownLatch和CyclicBarrier,1.7中又引入了Pha ...

  5. 《java.util.concurrent 包源码阅读》21 CyclicBarrier和CountDownLatch

    CyclicBarrier是一个用于线程同步的辅助类,它允许一组线程等待彼此,直到所有线程都到达集合点,然后执行某个设定的任务. 现实中有个很好的例子来形容:几个人约定了某个地方集中,然后一起出发去旅 ...

  6. 使用数据库乐观锁解决高并发秒杀问题,以及如何模拟高并发的场景,CyclicBarrier和CountDownLatch类的用法

    数据库:mysql 数据库的乐观锁:一般通过数据表加version来实现,相对于悲观锁的话,更能省数据库性能,废话不多说,直接看代码 第一步: 建立数据库表: CREATE TABLE `skill_ ...

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

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

  8. java多线程开发之CyclicBarrier,CountDownLatch

    最近研究了一个别人的源码,其中用到多个线程并行操作一个文件,并且在所有线程全部结束后才进行主线程后面的处理. 其用到java.util.concurrent.CyclicBarrier 这个类. Cy ...

  9. CyclicBarrier及CountDownLatch的使用

    CountDownLatch位于java.util.concurrent包下,是JDK1.5的并发包下的新特性. 首先根据Oracle的官方文档看看CountDownLatch的定义: A synch ...

随机推荐

  1. JavaScript预处理

    在预处理阶段js引擎会扫描代码中用var定义的变量和用声明的方式定义的函数 用声明方式定义函数 function a(){ alert('hello world'); } 用函数表达式定义函数 var ...

  2. 51. leetcode 530. Minimum Absolute Difference in BST

    530. Minimum Absolute Difference in BST Given a binary search tree with non-negative values, find th ...

  3. multiset与set

    set的含义是集合,它是一个有序的容器,里面的元素都是排序好的,支持插入,删除,查找等操作,就   像一个集合一样.所有的操作的都是严格在logn时间之内完成,效率非常高. set和multiset的 ...

  4. 微信小程序(有始有终,全部代码)开发--- 新增【录音】以及UI改进

    开篇语 寒假发了一篇练手文章,不出意外地火了: <简年15: 微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器 > 后来又发了BUG修复的版本,出乎意料的火了: 简年18: ...

  5. UIButton防止被重复点击

    一.避免屏幕内多个 UIButton 被重复点击 1.在 AppDelegate 中添加[[UIButton appearance] setExclusiveTouch:YES]; 2.button. ...

  6. 推荐——基于python

    资料来源: <集体智慧编程>&网络 一.推荐系统 概述 定义 维基百科定义: 推荐系统属于资讯过滤的一种应用. 推荐系统能够将可能受喜好的资讯或实物(例如:电影.电视节目.音乐.书 ...

  7. PyV8

    待完善 pyv8是个js解析引擎, PyV8 是 V8 引擎的 Python 语言封装,这是 Python 和 JavaScript 对象之间的桥,支持在 Python 脚本中调用 V8 引擎. # ...

  8. 使用 ESXi 虚拟化 Ryzen 1700

    最近开发的一个项目,需要多台机器支持,PC + 各种虚拟机,整得很乱,一怒之下,购买一台Ryzen 1700 + 32GB机器自行搭建服务器.经历两天时间,不停的踩坑,终于完成: Ryzen 1700 ...

  9. Deadclock on calling async methond

    Issue: HttpClient.GetAsync(…) never returns when using await/async Related Posts: http://stackoverfl ...

  10. 教程:基于访问控制的ABAP CDS视图权限

    Hi! 对每一个CDS视图,我们都可以通过DCL(Data Control Language)定义访问控制.在这篇文章中,我会介绍ABAP CDS视图中非常重要的一面:权限管理. 本文的阐述基于我正在 ...