IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]CyclicBarrier介绍

    lfsf802发表于 2015-02-27 15:22:41
    love 0

    简介

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

    成员

    此类有三个方法为:
    
    //设置parties、count及barrierCommand属性。
    CyclicBarrier(int)
    
    //当await的数量到达了设定的数量后,首先执行该Runnable对象。
    CyclicBarrier(int,Runnable)
    
    //通知barrier已完成线程
    await()
    

    应该场合

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

    实例程序

    package test;
    
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestCyclicBarrier {
        public static void main(String[] args) {
            ExecutorService service = Executors.newCachedThreadPool();
            final CyclicBarrier cb = new 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() + 1)
                                    + "个已到达"
                                    + (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊"
                                            : "正在等候"));
                            try {
                                cb.await();
                            } catch (BrokenBarrierException e) {
                                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) {
                                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) {
                                e.printStackTrace();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                service.execute(runnable);
            }
            service.shutdown();
        }
    }
    

    运行结果

    运行结果

    总结

    从上面的示例程序能够看出来,CyclicBarrier能够控制子线程等待,等到所有定义的子线程完成之后才能执行下一次的线程操作,当遇到这种情况的业务时候CyclicBarrier就会起到非常重要的作用。
    


沪ICP备19023445号-2号
友情链接