并发编程一波流之CyclicBarrier

并发编程一波流之CyclicBarrier

Peter Wei

 

 

CyclicBarrier介绍

一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 barrierCyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。

主要方法:

CyclicBarrier(int):

设置partiescountbarrierCommand属性。

CyclicBarrier(int,Runnable):

await的数量到达了设定的数量后,首先执行该Runnable对象。

await():

通知barrier已完成线程

应用场景

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

实例分析

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

 

主要类:

/**

 * 各省数据独立,分库存偖。为了提高计算性能,统计时采用每个省开一个线程先计算单省结果,最后汇总。

 *

 * @author guangbo email:weigbo@163.com

 *

 */

public class Total {

 

    // private ConcurrentHashMap result = new ConcurrentHashMap();

 

    public static void main(String[] args) {

       TotalService totalService = new TotalServiceImpl();

       CyclicBarrier barrier = new CyclicBarrier(5,

              new TotalTask(totalService));

 

       // 实际系统是查出所有省编码code的列表,然后循环,每个code生成一个线程。

       new BillTask(new BillServiceImpl(), barrier, "北京").start();

       new BillTask(new BillServiceImpl(), barrier, "上海").start();

       new BillTask(new BillServiceImpl(), barrier, "广西").start();

       new BillTask(new BillServiceImpl(), barrier, "四川").start();

       new BillTask(new BillServiceImpl(), barrier, "黑龙江").start();

 

    }

}

 

/**

 * 主任务:汇总任务

 */

class TotalTask implements Runnable {

    private TotalService totalService;

 

    TotalTask(TotalService totalService) {

       this.totalService = totalService;

    }

 

    public void run() {

       // 读取内存中各省的数据汇总,过程略。

       totalService.count();

       System.out.println("=======================================");

       System.out.println("开始全国汇总");

    }

}

 

/**

 * 子任务:计费任务

 */

class BillTask extends Thread {

    // 计费服务

    private BillService billService;

    private CyclicBarrier barrier;

    // 代码,按省代码分类,各省数据库独立。

    private String code;

 

    BillTask(BillService billService, CyclicBarrier barrier, String code) {

       this.billService = billService;

       this.barrier = barrier;

       this.code = code;

    }

 

    public void run() {

       System.out.println("开始计算--" + code + "--数据!");

       billService.bill(code);

       // bill方法结果存入内存,如ConcurrentHashMap,vector,代码略

       System.out.println(code + "省已经计算完成,并通知汇总Service");

       try {

           // 通知barrier已经完成

           barrier.await();

       } catch (InterruptedException e) {

           e.printStackTrace();

       } catch (BrokenBarrierException e) {

           e.printStackTrace();

       }

    }

 

}

 

结果:

开始计算--北京省--数据!

开始计算--上海省--数据!

北京省已经计算完成,并通知汇总Service

开始计算--四川省--数据!

四川省已经计算完成,并通知汇总Service

上海省已经计算完成,并通知汇总Service

开始计算--广西省--数据!

广西省已经计算完成,并通知汇总Service

开始计算--黑龙江省--数据!

黑龙江省已经计算完成,并通知汇总Service

=======================================

开始全国汇总

 

其它业务类

 

/**

 * @author guangbo

 *

 */

public interface BillService {

 

    /**

     * 各省计费

     *

     * @param code

     *            省编码

     */

    public void bill(String code);

 

}

 

/**

 * @author guangbo

 *

 */

public interface TotalService {

 

    /**

     * 汇总各省数据

     */

    public void count();

 

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值