• Java 多线程之栅栏-CyclicBarrier


             我们可以通过闭锁(CountDownLatch)来同时启动一组相关线程,或等待一组相关线程的结束。可是闭锁是一次性对象,一旦进入终止状态,就不能被重置。栅栏类似于闭锁,它能够阻塞一组线程直到某个事件发生。CyclicBarrier可以使一定数量的参与线程反复地在栅栏处汇集。如果希望创建一组任务,并行地执行工作,然后在下一步开始前等待;知道直到所有工作结束。这个就可以使用栅栏(CyclicBarrier)

        CyclicBarrier在并行迭代算法中是非常有用的:这种算法将一个问题拆分为一系列相对独立的子问题。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有线程被被释放,而栅栏被重置以便下次使用。如果对await调用超时或者await阻塞线程被中断,那么栅栏就被认为是打破了,所有阻塞的await调用都将抛出一个BrokenBarrierException.

    public class CyclicBarrier {
        
        private static class Generation {
            boolean broken = false;
        }
    
        /** 栅栏入口的锁 */
        private final ReentrantLock lock = new ReentrantLock();
        /** 一直等待到跳闸的条件 */
        private final Condition trip = lock.newCondition();
        /** 缔约方数量 */
        private final int parties;
        /*跳闸时执行的命令 */
        private final Runnable barrierCommand;
        
        private Generation generation = new Generation();
    
        /**
         *  尚未等待的缔约方数量
         */
        private int count;
    
        /**
         * 获取下一代
         */
        private void nextGeneration() {
        
            trip.signalAll();
           
            count = parties;
            generation = new Generation();
        }
    
        /**
    	 * 设置当前栅栏代被打破,唤醒所有等待线程
         */
        private void breakBarrier() {
            generation.broken = true;
            count = parties;
            trip.signalAll();
        }
    
        /**
         * Main barrier code, covering the various policies.
         */
        private int dowait(boolean timed, long nanos)
            throws InterruptedException, BrokenBarrierException,
                   TimeoutException {
    		//重入锁
            final ReentrantLock lock = this.lock;
    		// 锁
            lock.lock();
            try {
                final Generation g = generation;
    			// 如果当前一代栅栏已经跳闸则抛出异常
                if (g.broken)
                    throw new BrokenBarrierException();
    			// 如果线程中断则打开栅栏
                if (Thread.interrupted()) {
                    breakBarrier();
                    throw new InterruptedException();
                }
    			// 等待线程自减
                int index = --count;
    			// 如果当前线程已经是最后一个线程,则执行回调同时代开栅栏
                if (index == 0) {  // tripped
                    boolean ranAction = false;
                    try {
                        final Runnable command = barrierCommand;
                        if (command != null)
                            command.run();
                        ranAction = true;
                        nextGeneration();
                        return 0;
                    } finally {
                        if (!ranAction)
                            breakBarrier();
                    }
                }
    			// 一直循环直到栅栏跳闸,打开,中断或超时
                for (;;) {
                    try {
                        if (!timed)
                            trip.await();
                        else if (nanos > 0L)
                            nanos = trip.awaitNanos(nanos);
                    } catch (InterruptedException ie) {
                        if (g == generation && ! g.broken) {
                            breakBarrier();
                            throw ie;
                        } else {
                        
                            Thread.currentThread().interrupt();
                        }
                    }
    
                    if (g.broken)
                        throw new BrokenBarrierException();
    
                    if (g != generation)
                        return index;
    
                    if (timed && nanos <= 0L) {
                        breakBarrier();
                        throw new TimeoutException();
                    }
                }
            } finally {
                lock.unlock();
            }
        }
    
        /**
    	 * 创建一个新的CyclicBarrier,他会在指定数量的线程都在等待是跳闸,最后一个线程通过栅栏后执行栅栏回调处理
         */
        public CyclicBarrier(int parties, Runnable barrierAction) {
            if (parties <= 0) throw new IllegalArgumentException();
    		// 缔约方数量是指定的线程数
            this.parties = parties;
    		//等待线程数
            this.count = parties;
    		//栅栏命令
            this.barrierCommand = barrierAction;
        }
    
        /**
         */
        public CyclicBarrier(int parties) {
            this(parties, null);
        }
    
        /**
         * 获取缔约方数量
         */
        public int getParties() {
            return parties;
        }
    
        /**
         * 一直阻塞到所有的缔约方都调用这个方法
         */
        public int await() throws InterruptedException, BrokenBarrierException {
            try {
                return dowait(false, 0L);
            } catch (TimeoutException toe) {
                throw new Error(toe); // cannot happen
            }
        }
    
       
        public int await(long timeout, TimeUnit unit)
            throws InterruptedException,
                   BrokenBarrierException,
                   TimeoutException {
            return dowait(true, unit.toNanos(timeout));
        }
    
        /**
         * 查询当前栅栏是否被打破
         */
        public boolean isBroken() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                return generation.broken;
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * 重置栅栏
         */
        public void reset() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                breakBarrier();   // break the current generation
                nextGeneration(); // start a new generation
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * 获取等待的线程数量
         */
        public int getNumberWaiting() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                return parties - count;
            } finally {
                lock.unlock();
            }
        }
    }
    

             加入我们有一个汽车竞速赛事,同时启动最先到达终点的汽车胜出。赛事里程是固定的,我们可以将时间分割成很小的一段,每辆汽车在这一段时间行驶的里程是不同的。

    /**
     *
     * @author zhangwei_david
     * @version $Id: Horser.java, v 0.1 2015年7月3日 下午3:15:40 zhangwei_david Exp $
     */
    public class Car implements Runnable {
    
        /**
         * 汽车ID
         */
        private final String         id;
    
        /**
         * 门闸
         */
        private static CyclicBarrier cyclicBarrier;
        /**
         * 里程
         */
        private AtomicInteger        strides = new AtomicInteger(0);
    
        private static Random        rand    = new Random(47);
    
        public Car(CyclicBarrier barrier, String id) {
            cyclicBarrier = barrier;
            this.id = id;
        }
    
        public int getStrides() {
            return strides.get();
        }
    
        /**
         * @see java.lang.Runnable#run()
         */
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    synchronized (this) {
                        strides.set(strides.get() + rand.nextInt(3));
                    }
                    // 准备了可以开始,当门闸所有的线程都已经调用了await方法则可以继续执行
                    cyclicBarrier.await();
                }
            } catch (InterruptedException e) {
    
            } catch (BrokenBarrierException be) {
                throw new RuntimeException(be);
            }
        }
    
        /**
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return " [car " + id + "]";
        }
    
        public String tracks() {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < getStrides(); i++) {
                sb.append("-");
            }
            sb.append(id);
            return sb.toString();
    
        }
    
    }
    /**
     * 汽车拉力赛的类
     *
     * @author zhangwei_david
     * @version $Id: HorseRace.java, v 0.1 2015年7月3日 下午10:27:44 zhangwei_david Exp $
     */
    public class CarRace {
    
        /**
         * 指定赛道长度
         */
        private static final int   FINISH_LINE = 75;
    
        /**
         * 赛道标尺线
         */
        public static final String TRACK       = "===========================================================================";
    
        /**
         * 参赛汽车
         */
        private List<Car>          cars        = new ArrayList<Car>();
    
        private ExecutorService    service     = Executors.newCachedThreadPool();
    
        /**
         * 门闸
         */
        private CyclicBarrier      barrier;
    
        
        public CarRace(int nCars) {
            /**
             * 创建一个执行线程数量的CyclicBarrier,当所有现在都准备好以后则CyclicBarrier可以开闸放行,此时回调给定的barrierAction
             *
             */
            barrier = new CyclicBarrier(nCars, new Runnable() {
    
                public void run() {
    
                    printEvent();
                    judge();
                    try {
                        TimeUnit.MILLISECONDS.sleep(200);
                    } catch (Exception e) {
    
                    }
                }
    
                /**
                 * 裁判
                 */
                private void judge() {
                    for (Car car : cars) {
                        if (car.getStrides() >= FINISH_LINE) {
                            System.out.println(car + " won!");
                            service.shutdownNow();
                            return;
                        }
                    }
                }
    
                /**
                 * 赛事实况
                 */
                private void printEvent() {
                    System.out.println(TRACK);
                    for (Car car : cars) {
                        System.out.println(car.tracks());
                    }
                    System.out.println(TRACK);
                }
            });
            for (int i = 0; i < nCars; i++) {
                Car car = new Car(barrier, String.valueOf(i));
                cars.add(car);
                service.execute(car);
            }
        }
    
        public static void main(String[] args) {
            new CarRace(7);
        }
    }
    
    ===========================================================================
    --0
    --1
    -2
    --3
    -4
    --5
    -6
    ===========================================================================
    ===========================================================================
    ---0
    --1
    --2
    --3
    -4
    --5
    ---6
    ===========================================================================
    ===========================================================================
    ----0
    ---1
    ----2
    ----3
    --4
    ---5
    ----6
    ===========================================================================
    ===========================================================================
    ----0
    -----1
    -----2
    ------3
    ---4
    ---5
    ----6
    ===========================================================================
    ===========================================================================
    ----0
    ------1
    ------2
    -------3
    ----4
    -----5
    ----6
    ===========================================================================
    ===========================================================================
    ----0
    ------1
    -------2
    ---------3
    -----4
    -----5
    ----6
    ===========================================================================
    ===========================================================================
    -----0
    --------1
    --------2
    ---------3
    -----4
    ------5
    -----6
    ===========================================================================
    ===========================================================================
    -------0
    ---------1
    ----------2
    ----------3
    ------4
    ------5
    ------6
    ===========================================================================
    ===========================================================================
    -------0
    ---------1
    ------------2
    -----------3
    ------4
    ------5
    ------6
    ===========================================================================
    ===========================================================================
    -------0
    -----------1
    ------------2
    ------------3
    --------4
    -------5
    -------6
    ===========================================================================
    ===========================================================================
    -------0
    -------------1
    ------------2
    --------------3
    --------4
    -------5
    --------6
    ===========================================================================
    ===========================================================================
    ---------0
    ---------------1
    -------------2
    ---------------3
    ----------4
    -------5
    ----------6
    ===========================================================================
    ===========================================================================
    -----------0
    ---------------1
    --------------2
    ---------------3
    ----------4
    --------5
    ------------6
    ===========================================================================
    ===========================================================================
    ------------0
    ----------------1
    ----------------2
    ---------------3
    ------------4
    --------5
    ------------6
    ===========================================================================
    ===========================================================================
    ------------0
    ----------------1
    ------------------2
    ---------------3
    -------------4
    --------5
    --------------6
    ===========================================================================
    ===========================================================================
    --------------0
    -----------------1
    --------------------2
    ---------------3
    ---------------4
    ---------5
    --------------6
    ===========================================================================
    ===========================================================================
    ----------------0
    -------------------1
    ---------------------2
    ----------------3
    -----------------4
    ---------5
    ---------------6
    ===========================================================================
    ===========================================================================
    -----------------0
    --------------------1
    ---------------------2
    ----------------3
    -----------------4
    -----------5
    ----------------6
    ===========================================================================
    ===========================================================================
    -------------------0
    --------------------1
    ----------------------2
    ----------------3
    -----------------4
    -------------5
    ----------------6
    ===========================================================================
    ===========================================================================
    ---------------------0
    ---------------------1
    ----------------------2
    ------------------3
    -----------------4
    ---------------5
    -----------------6
    ===========================================================================
    ===========================================================================
    ----------------------0
    ---------------------1
    ----------------------2
    --------------------3
    -------------------4
    -----------------5
    -------------------6
    ===========================================================================
    ===========================================================================
    -----------------------0
    ----------------------1
    ----------------------2
    ----------------------3
    -------------------4
    -------------------5
    ---------------------6
    ===========================================================================
    ===========================================================================
    ------------------------0
    ----------------------1
    ------------------------2
    -----------------------3
    --------------------4
    -------------------5
    -----------------------6
    ===========================================================================
    ===========================================================================
    --------------------------0
    ----------------------1
    --------------------------2
    -------------------------3
    --------------------4
    -------------------5
    -------------------------6
    ===========================================================================
    ===========================================================================
    --------------------------0
    ----------------------1
    ---------------------------2
    ---------------------------3
    --------------------4
    --------------------5
    -------------------------6
    ===========================================================================
    ===========================================================================
    ---------------------------0
    ------------------------1
    -----------------------------2
    ---------------------------3
    ---------------------4
    ---------------------5
    --------------------------6
    ===========================================================================
    ===========================================================================
    ---------------------------0
    -------------------------1
    -------------------------------2
    ---------------------------3
    ----------------------4
    ---------------------5
    ----------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------0
    --------------------------1
    -------------------------------2
    ---------------------------3
    -----------------------4
    ----------------------5
    ------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------0
    --------------------------1
    --------------------------------2
    -----------------------------3
    ------------------------4
    ----------------------5
    --------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------0
    ---------------------------1
    ----------------------------------2
    -------------------------------3
    --------------------------4
    ----------------------5
    ---------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------0
    ---------------------------1
    ----------------------------------2
    ---------------------------------3
    --------------------------4
    ------------------------5
    -----------------------------------6
    ===========================================================================
    ===========================================================================
    ---------------------------------0
    ----------------------------1
    -----------------------------------2
    ----------------------------------3
    ---------------------------4
    ------------------------5
    -----------------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------------0
    ----------------------------1
    -------------------------------------2
    ----------------------------------3
    ---------------------------4
    -------------------------5
    -----------------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------------0
    ------------------------------1
    ---------------------------------------2
    -----------------------------------3
    ---------------------------4
    ---------------------------5
    -------------------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------------0
    ------------------------------1
    ----------------------------------------2
    ------------------------------------3
    ---------------------------4
    -----------------------------5
    -------------------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------------0
    -------------------------------1
    ------------------------------------------2
    ------------------------------------3
    ---------------------------4
    -----------------------------5
    -------------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------------0
    --------------------------------1
    ------------------------------------------2
    -------------------------------------3
    ---------------------------4
    -----------------------------5
    ---------------------------------------6
    ===========================================================================
    ===========================================================================
    --------------------------------------0
    ----------------------------------1
    ------------------------------------------2
    ---------------------------------------3
    ---------------------------4
    ------------------------------5
    ---------------------------------------6
    ===========================================================================
    ===========================================================================
    ----------------------------------------0
    ------------------------------------1
    --------------------------------------------2
    ---------------------------------------3
    -----------------------------4
    -------------------------------5
    ----------------------------------------6
    ===========================================================================
    ===========================================================================
    ----------------------------------------0
    --------------------------------------1
    ----------------------------------------------2
    ----------------------------------------3
    -------------------------------4
    -------------------------------5
    -----------------------------------------6
    ===========================================================================
    ===========================================================================
    ----------------------------------------0
    ---------------------------------------1
    -----------------------------------------------2
    -----------------------------------------3
    -------------------------------4
    ---------------------------------5
    -------------------------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------------------0
    -----------------------------------------1
    ------------------------------------------------2
    ------------------------------------------3
    -------------------------------4
    -----------------------------------5
    ---------------------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------------------0
    -------------------------------------------1
    ------------------------------------------------2
    -------------------------------------------3
    ---------------------------------4
    ------------------------------------5
    ---------------------------------------------6
    ===========================================================================
    ===========================================================================
    --------------------------------------------0
    -------------------------------------------1
    ------------------------------------------------2
    -------------------------------------------3
    ---------------------------------4
    ------------------------------------5
    -----------------------------------------------6
    ===========================================================================
    ===========================================================================
    --------------------------------------------0
    ---------------------------------------------1
    --------------------------------------------------2
    -------------------------------------------3
    -----------------------------------4
    -------------------------------------5
    -------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ----------------------------------------------0
    ----------------------------------------------1
    --------------------------------------------------2
    -------------------------------------------3
    -------------------------------------4
    -------------------------------------5
    --------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------------------------0
    -----------------------------------------------1
    ---------------------------------------------------2
    ---------------------------------------------3
    ---------------------------------------4
    --------------------------------------5
    ----------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------------------------0
    ------------------------------------------------1
    -----------------------------------------------------2
    ---------------------------------------------3
    ----------------------------------------4
    ----------------------------------------5
    -----------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ---------------------------------------------------0
    --------------------------------------------------1
    ------------------------------------------------------2
    ----------------------------------------------3
    ----------------------------------------4
    -----------------------------------------5
    -------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ----------------------------------------------------0
    ---------------------------------------------------1
    --------------------------------------------------------2
    ------------------------------------------------3
    ------------------------------------------4
    ------------------------------------------5
    --------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------------------------------0
    -----------------------------------------------------1
    ----------------------------------------------------------2
    ------------------------------------------------3
    ------------------------------------------4
    ------------------------------------------5
    ----------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------------------------------0
    -------------------------------------------------------1
    -----------------------------------------------------------2
    ------------------------------------------------3
    ------------------------------------------4
    ------------------------------------------5
    ------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------------------------------0
    --------------------------------------------------------1
    ------------------------------------------------------------2
    ------------------------------------------------3
    -------------------------------------------4
    -------------------------------------------5
    -------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------------------------------0
    ---------------------------------------------------------1
    ------------------------------------------------------------2
    --------------------------------------------------3
    -------------------------------------------4
    ---------------------------------------------5
    --------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------------------------------0
    ----------------------------------------------------------1
    ------------------------------------------------------------2
    ----------------------------------------------------3
    ---------------------------------------------4
    -----------------------------------------------5
    --------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    --------------------------------------------------------0
    ------------------------------------------------------------1
    ------------------------------------------------------------2
    ------------------------------------------------------3
    ---------------------------------------------4
    -------------------------------------------------5
    ---------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ----------------------------------------------------------0
    --------------------------------------------------------------1
    -------------------------------------------------------------2
    ------------------------------------------------------3
    -----------------------------------------------4
    ---------------------------------------------------5
    ----------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------------------------------------0
    ----------------------------------------------------------------1
    ---------------------------------------------------------------2
    ------------------------------------------------------3
    -----------------------------------------------4
    -----------------------------------------------------5
    ------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------------------------------------0
    -----------------------------------------------------------------1
    ---------------------------------------------------------------2
    ------------------------------------------------------3
    -----------------------------------------------4
    -----------------------------------------------------5
    -------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------------------------------------0
    -------------------------------------------------------------------1
    ---------------------------------------------------------------2
    -------------------------------------------------------3
    -------------------------------------------------4
    -------------------------------------------------------5
    --------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ---------------------------------------------------------------0
    -------------------------------------------------------------------1
    -----------------------------------------------------------------2
    --------------------------------------------------------3
    --------------------------------------------------4
    -------------------------------------------------------5
    --------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ---------------------------------------------------------------0
    -------------------------------------------------------------------1
    -----------------------------------------------------------------2
    ---------------------------------------------------------3
    ----------------------------------------------------4
    --------------------------------------------------------5
    ----------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -----------------------------------------------------------------0
    -------------------------------------------------------------------1
    -----------------------------------------------------------------2
    ----------------------------------------------------------3
    -----------------------------------------------------4
    --------------------------------------------------------5
    ------------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    ------------------------------------------------------------------0
    --------------------------------------------------------------------1
    -------------------------------------------------------------------2
    -----------------------------------------------------------3
    -------------------------------------------------------4
    ---------------------------------------------------------5
    --------------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------------------------------------------0
    ----------------------------------------------------------------------1
    -------------------------------------------------------------------2
    -----------------------------------------------------------3
    --------------------------------------------------------4
    ---------------------------------------------------------5
    --------------------------------------------------------------------------6
    ===========================================================================
    ===========================================================================
    -------------------------------------------------------------------0
    -----------------------------------------------------------------------1
    --------------------------------------------------------------------2
    -------------------------------------------------------------3
    ----------------------------------------------------------4
    ---------------------------------------------------------5
    ---------------------------------------------------------------------------6
    ===========================================================================
     [car 6] won!
  • 相关阅读:
    互联网创业的葵花宝典
    null和undefined的区别
    mpc0.9编译方法
    gmp5.0.5编译
    为iphone及iphone simulator编译poco库
    binutils2.22编译心得
    为iphone及iphone simulator编译qt库
    sql server之触发器调用C#CLR存储过程实现两个表的数据同步
    poco之HttpRequest之get方法
    poco之HttpRequest之post方法
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797756.html
Copyright © 2020-2023  润新知