美文网首页
CyclicBarrier使用及应用场景例子

CyclicBarrier使用及应用场景例子

作者: 联想桥南 | 来源:发表于2018-01-07 20:46 被阅读0次
    CyclicBarrier是什么?

    JDK1.5开始提供的并发编程,辅助工具类。用于并发编程的。

    字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。
    叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。
    叫做栅栏,大概是描述所有线程被栅栏挡住了,当都达到时,一起跳过栅栏执行,也算形象。我们可以把这个状态就叫做barrier。

    通过CyclicBarrier的await()方法,线程就处于barrier状态。

    CyclicBarrier如何使用和工作?

    看下API
    CyclicBarrier有两个构造函数

    public CyclicBarrier(int parties)
    public CyclicBarrier(int parties, Runnable barrierAction)
    

    第一个参数,表示那个一起执行的线程个数。
    第二个参数,表示线程都处于barrier时,一起执行之前,先执行的一个线程。

    让线程处于barrier状态的方法await()

    public int await()
    public int await(long timeout, TimeUnit unit)
    

    第一个默认方法,表示要等到所有的线程都处于barrier状态,才一起执行
    第二个方法,指定了等待的时间,当所有线程没有都处于barrier状态,又到了指定的时间,所在的线程就继续执行了。

    CyclicBarrier应用场景例子

    举个报旅行团旅行的例子。
    出发时,导游会在机场收了护照和签证,办理集体出境手续,所以,要等大家都到齐才能出发,出发前再把护照和签证发到大家手里。
    对应CyclicBarrier使用。
    每个人到达后进入barrier状态。
    都到达后,唤起大家一起出发去旅行。
    旅行出发前,导游还会有个发护照和签证的动作。
    代码如下:

    /**
     * 旅行线程
     * Created by jiapeng on 2018/1/7.
     */
    public class TravelTask implements Runnable{
    
        private CyclicBarrier cyclicBarrier;
        private String name;
        private int arriveTime;//赶到的时间
    
        public TravelTask(CyclicBarrier cyclicBarrier,String name,int arriveTime){
            this.cyclicBarrier = cyclicBarrier;
            this.name = name;
            this.arriveTime = arriveTime;
        }
    
        @Override
        public void run() {
            try {
                //模拟达到需要花的时间
                Thread.sleep(arriveTime * 1000);
                System.out.println(name +"到达集合点");
                cyclicBarrier.await();
                System.out.println(name +"开始旅行啦~~");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 导游线程,都到达目的地时,发放护照和签证
     * Created by jiapeng on 2018/1/7.
     */
    public class TourGuideTask implements Runnable{
    
        @Override
        public void run() {
            System.out.println("****导游分发护照签证****");
            try {
                //模拟发护照签证需要2秒
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * Created by jiapeng on 2018/1/7.
     */
    public class Client {
    
        public static void main(String[] args) throws Exception{
    
            CyclicBarrier cyclicBarrier = new CyclicBarrier(3,new TourGuideTask());
            Executor executor = Executors.newFixedThreadPool(3);
            //登哥最大牌,到的最晚
            executor.execute(new TravelTask(cyclicBarrier,"哈登",5));
            executor.execute(new TravelTask(cyclicBarrier,"保罗",3));
            executor.execute(new TravelTask(cyclicBarrier,"戈登",1));
        }
    }
    
    执行结果
    CyclicBarrier的底层原理

    CyclicBarrier类是concurrent并发包下的一工具类。
    线程间同步阻塞是使用的是ReentrantLock,可重入锁
    线程间通信使用的是Condition,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用。

    相关文章

      网友评论

          本文标题:CyclicBarrier使用及应用场景例子

          本文链接:https://www.haomeiwen.com/subject/ilspnxtx.html