美文网首页Java-多线程
CyclicBarrier 实现阶段性同步

CyclicBarrier 实现阶段性同步

作者: PageThinker | 来源:发表于2020-04-15 16:30 被阅读0次

    01 CyclicBarrier

    01.png

    CyclicBarrier 提供了如下功能:

    (1)向上增加计数的功能

    (2)阻塞等待功能

    (3)阶段性同步功能(线程数大于 parties 数量时)

    (4)支持多次循环实现多个线程一起执行的目的。


    02 与 CountDownLatch 的比较

    (1)CountDownLatch 时计数器做减法,而 CyclicBarrier 时通过累加来实现。

    (2)CountDownLatch 只支持单次多个线程阻塞然后一起执行,CyclicBarrier 是支持多次的。


    03 常用方法

    await() 阻塞等待,直到达到构造函数中指定的数量之后继续向下执行。

    getNumberWaiting() 获取有几个线程已到了阻塞节点

    isBroken() 查询阻塞是否受到损坏,这里的损坏指的是当出现异常后 阻塞节点是否还能够正常工作。

    例如: 5 个线程线程阻塞时有一个线程抛出了 NullPointException,那么只有抛出 NullPointException 的线程停止运行,其他 4 个线程依然在运行。

    再比如:5 个线程中有一个线程执行了 interruput() 中断,那么其他几个阻塞等待的线程都会停止运行。阻塞节点被破坏。

    getParties() 获取构造函数中指定的 parties 数

    reset() 重置阻塞。


    04 案例

    10 个运动员(Runner)参加淘汰赛,两两一组比赛。

    Runner.java

    package com.page.concurrent.cyclicbarrier;
    
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    public class Runner extends Thread {
        private final CyclicBarrier cyclicBarrier;
        private final int number;
    
        public Runner(CyclicBarrier cyclicBarrier, int number) {
            this.cyclicBarrier = cyclicBarrier;
            this.number = number;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()
                    + ":"
                    + System.currentTimeMillis()
                    + " Ready. Waiting another one.");
    
    
            try {
                Thread.sleep(1000 * number);
                cyclicBarrier.await();
    
                System.out.println(Thread.currentThread().getName() + " run.");
            } catch (InterruptedException e) {
                System.out.println("had exception when waiting others. e=" + e.getMessage());
            } catch (BrokenBarrierException e) {
                System.out.println("had exception when waiting others. e" + e.getMessage());
            }
    
    
        }
    }
    
    

    Game.java

    package com.page.concurrent.cyclicbarrier;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.CyclicBarrier;
    
    public class Game {
        public static void main(String[] args) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(2,
                    () -> System.out.println(System.currentTimeMillis() + ">>>> 2 runner had ready."));
            List<Runner> runners = new ArrayList<>();
            for (int i = 1; i <= 10; i++) {
                Runner runner = new Runner(cyclicBarrier, i);
                runner.start();
                runners.add(runner);
            }
    
    
        }
    }
    
    
    02.png

    相关文章

      网友评论

        本文标题:CyclicBarrier 实现阶段性同步

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