栅栏CyclicBarrier

本文通过一个具体的示例,展示了如何使用 Java 中的 CyclicBarrier 类来同步多个线程,确保它们达到某个公共的同步点后再一并继续执行。这个例子模拟了四位游客同时到达公园的情景。

它允许一组线程互相等待,直到到达某个公共屏障点。利用栅栏,可以使线程相互等待,直到所有线程都到达某一点,然后栅栏将打开,所有线程将通过栅栏继续执行。CyclicBarrier支持一个可选的 Runnable 参数,当线程通过栅栏时,runnable对象将被调用。构造函数CyclicBarrier(int parties, Runnable barrierAction),当线程在CyclicBarrier对象上调用await()方法时,栅栏的计数器将增加1,当计数器为parties(设定的需要相互等待的线程数)时,栅栏将打开。

publicclass BarrierVisitors
{
    publicstaticvoid main(String[] args){
        final String[] visitors =new String[] {"甲","乙","丙","丁" };
        finalint visitorNum = visitors.length;
        final SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //设置栅栏,四个游客全部到达后一起进入公园
        final CyclicBarrier arrived =new CyclicBarrier(visitorNum,new Runnable() {
            @Override
            publicvoid run() {
                Date arrivedDate =new Date(System.currentTimeMillis());
                System.out.println(sdf.format(arrivedDate) +" all Arrived!");
            }
        });
       
        for(int i = 0; i < visitorNum; i++){
            new Thread(new BarrierVisitor(visitors[i], sdf,
                            arrived)).start();
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                //TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }  
}
class BarrierVisitorimplements Runnable{
    final CyclicBarrier  arrived;
    final String          name;
    final SimpleDateFormatsdf;
    public BarrierVisitor(final String name, SimpleDateFormat sdf,
                    final CyclicBarrier arrived){
        this.name = name;
        this.arrived = arrived;
        this.sdf = sdf;
    }
    @Override
    publicvoid run(){
        try{           
            //各自从家里出发,模拟从家出发到公园门口
            Date startDate = new Date(System.currentTimeMillis());
            System.out.println(sdf.format(startDate) +" " + this.name
                            + " begin going to the park!");
            Thread.sleep((long) (Math.random() * 10000));
        }catch(Throwable e){
            e.printStackTrace();
        }finally{
            //到达公园
            Date arrivedDate = new Date(System.currentTimeMillis());
            System.out.println(sdf.format(arrivedDate) +" " + this.name
                            + " arrived the park!");
            try{
                arrived.await();
            }catch(InterruptedException e){
                e.printStackTrace();
            }catch(BrokenBarrierException e){
                e.printStackTrace();
            }
        }
    }  
}
输出结果:

2013-10-09 10:38:03  begin going to the park!

2013-10-09 10:38:04  begin going to the park!

2013-10-09 10:38:05  begin going to the park!

2013-10-09 10:38:06  begin going to the park!

2013-10-09 10:38:09  arrived the park!

2013-10-09 10:38:09  arrived the park!

2013-10-09 10:38:12  arrived the park!

2013-10-09 10:38:14  arrived the park!

2013-10-09 10:38:14 all Arrived!


当4个人都到达公园时,都调用了一次await()方法,使栅栏的计数器变为4,等于visitorNum,所以栅栏将打开,执行内部 Runnable里的run方法。


CountDownLatch 是一个计数器,它可以让一个或多个线程等待其他线程执行完毕后再继续执行。它的主要方法是 countDown() 和 await(),其中 countDown() 用于计数减一,await() 用于等待计数器变为0。与 CountDownLatch 相比,CyclicBarrier 的主要区别在于它可以重复使用,而且所有线程必须同时到达栅栏处才能继续执行后续任务。CyclicBarrier 的重要方法是 await(),并且可以通过构造方法传入一个 Runnable,在所有线程都到达栅栏状态时优先执行该动作。CyclicBarrier 内部使用 ReentrantLock 和 Condition 实现等待和唤醒的功能,通过维护一个 count 变量来记录还有多少个线程没有到达栅栏处。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CountDownLatch与CyclicBarrier](https://blog.youkuaiyun.com/weixin_44442186/article/details/123985119)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JUC多线程:CountDownLatch、CyclicBarrier、Semaphore同步器原理总结](https://blog.youkuaiyun.com/a745233700/article/details/120688546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值