JAVA concurrent包学习--CyclicBarrier

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 cb1
cb1 test
runner:4 wait for begin...0
runner:3 wait for begin...0
runner:2 wait for begin...0
runner:0 wait for begin...0
runner:1 wait for begin...0
runner:0 wait over cost:102ms
is broken?:false
runner:1 wait over cost:556ms
is broken?:false
execute runable
runner:1 begin execute...
runner:0 begin execute...
runner:4 wait over cost:765ms
runner:2 wait over cost:764ms
is broken?:false
is broken?:false
execute runable
runner:4 begin execute...
runner:2 begin execute...
runner:3 wait over cost:916ms
is broken?:false

参考博文

博文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值