首页 > 代码库 > Java并发之CyclicBarria的使用

Java并发之CyclicBarria的使用

Java并发之CyclicBarria的使用

一.简介

  笔者在写CountDownLatch这个类的时候,看到了博客园上的《浅析Java中CountDownLatch用法》这篇博文,为博主扎实的技术功底所折服,对Java多线程方面的只是信手拈来,首先在此感谢博主给了我灵感,让我进一步了解了CountDownLatch的用法,在此请收下小弟的膝盖(如果博主能够看到的化)。借着《浅析Java中CountDownLatch用法》这篇博文,笔者想借着这个例子说一下 CyclicBarria的用法。CyclicBarria中文翻译过来就是"循环栅栏"。

二. CyclicBarria的使用

  读者如果读到该文章,请先观看一下 《浅析Java中CountDownLatch用法》这篇文章,笔者只是借助于该博文作者,稍稍作了写修改,用CyclicBarria来实现。代码如下:

public class CyclicBarriaTest2 {

    private static final int PLAYER_AMOUNT = 5;  //五个运动员
    
    private static ExecutorService exe = Executors.newFixedThreadPool(PLAYER_AMOUNT);
    
    static class Command implements Runnable {

        private boolean flag;
        
        public Command(boolean flag){
            this.flag = flag;
        }
        
        @Override
        public void run() {
            if(flag){
                System.out.println("比赛开始...");
                flag = false;
            }else{
                System.out.println("比赛结束...");
                exe.shutdown();
            }
        }
    }
    
    public static void main(String[] args) {
        /**
         * 循环栅栏。当cb调用 await()方法的时候,当5个线程全部就绪,就执行 Command实例化的线程,
         * 当所有线程,执行完毕,后又碰到await()方法,就等5个线程全部执行完毕, 然后再执行Command的实例
         * 线程。
         */
        CyclicBarrier cb = new CyclicBarrier(5, new Command(true));
        
        Player[] plays = new Player[PLAYER_AMOUNT];
        
        for(int i = 0; i < PLAYER_AMOUNT; i++) {
            plays[i] = new Player(i+1, cb);
        }
        
        for(Player p:plays) {
            exe.execute(p);            //分配线程
        }
    }
}

    Player类的实现如下:

class Player implements Runnable{
    
    private int num;
    private CyclicBarrier cb;
    
    public Player(int num, CyclicBarrier cb){
        this.num = num;
        this.cb = cb;
    }
    
    @Override
    public void run() {
        try {
            cb.await();  //等待所有线程就绪,执行cb中的线程。
            
            Thread.sleep((long)(Math.random() * 100));    //随机分配时间,即运动员完成时间
            System.out.println("Play" + num + " arrived.");
            
            cb.await(); //当所有线程执行完毕,再去执行cb中的线程
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

 

Java并发之CyclicBarria的使用