Board logo

标题: 多线程---java判断多线程结束(3) [打印本页]

作者: look_w    时间: 2019-5-11 14:12     标题: 多线程---java判断多线程结束(3)

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


主要方法
//设置parties、count及barrierCommand属性。
CyclicBarrier(int):

//当await的数量到达了设定的数量后,首先执行该Runnable对象。
CyclicBarrier(int,Runnable):

//通知barrier已完成线程
await():






使用例子

    我们需要统计全国的业务数据。其中各省的数据库是独立的,也就是说按省分库。并且统计的数据量很大,统计过程也比较慢。为了提高性能,快速计算。我们采取并发的方式,多个线程同时计算各省数据,最后再汇总统计。在这里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!




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0