JAVA concurrent包学习--CyclicBarrier

来源:互联网 发布:ubuntu 安装mysql5.7 编辑:程序博客网 时间:2024/04/20 06:26

CyclicBarrier

简介

CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

方法列表

CyclicBarrier(int parties)创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。CyclicBarrier(int parties, Runnable barrierAction)创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。int await()在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。int await(long timeout, TimeUnit unit)在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间。int getNumberWaiting()返回当前在屏障处等待的参与者数目。int getParties()返回要求启动此 barrier 的参与者数目。boolean isBroken()查询此屏障是否处于损坏状态。void reset()将屏障重置为其初始状态。

个人理解

CyclicBarrier个人理解成一个关卡(可以循环使用),该关卡放行的条件是当前在关卡等待的人数达到一定数量(parties),然后一次性放行,该关卡恢复成初始状态(当parties,该方法的作用类似于一个监听器)

关键操作

执行await()操作 都将被阻塞 直到满足阻塞的线程数=parties 若barrierAction不为空 执行barrierAction 这些线程都将继续执行 关卡重新设卡
执行await(long timeout, TimeUnit unit)操作 设置的wait时间 未超时的作用和await操作一致 若等待超时,将损坏关卡 该关卡将暂不可用(直到执行reset方法) 所有当前await状态的线程和之后执行await操作的线程将抛出异常

执行reset()将使所有尚在await的线程将抛出异常,然后重置关卡,恢复正常

使用场景

示例代码(java 1.8)

public static void main(String[] args) {        CyclicBarrier cb = new CyclicBarrier(2, ()->{            System.out.println("execute runable");        });        CyclicBarrier cb1 = new CyclicBarrier(1, ()->{            System.out.println("execute runable cb1");        });        new Thread(()->{            try {                cb1.await();            } catch (Exception e) {                e.printStackTrace();            }            System.out.println("cb1 test");        }).start();        AtomicInteger ai = new AtomicInteger();        for (int i = 0; i < 5; i++) {            int j = i;            new Thread(()->{                try {                    System.out.println(String.format("runner:%s wait for begin...%s", j, cb.getNumberWaiting()));                    long st = System.currentTimeMillis();                    Thread.sleep(100+new Random().nextInt(900));                    long et = System.currentTimeMillis();                    System.out.println(String.format("runner:%s wait over cost:%sms", j, (et-st)));                    System.out.println(String.format("is broken?:%s", cb.isBroken()));                    int curNum = ai.getAndIncrement();                    if(curNum==4){                        cb.reset();                    }                    if(curNum==2){                        cb.await(5, TimeUnit.SECONDS);                    }else{                        cb.await();                    }                    System.out.println(String.format("runner:%s begin execute...", j));                } catch (Exception e) {                    e.printStackTrace();                }            }).start();        }    }

输出结果

execute runable cb1cb1 testrunner:4 wait for begin...0runner:3 wait for begin...0runner:2 wait for begin...0runner:0 wait for begin...0runner:1 wait for begin...0runner:0 wait over cost:102msis broken?:falserunner:1 wait over cost:556msis broken?:falseexecute runablerunner:1 begin execute...runner:0 begin execute...runner:4 wait over cost:765msrunner:2 wait over cost:764msis broken?:falseis broken?:falseexecute runablerunner:4 begin execute...runner:2 begin execute...runner:3 wait over cost:916msis broken?:false

参考博文

博文链接

0 0