并发编程CyclicBarrier应用以及与countDownLatch的区别

CyclicBarrier其实和CountdownLatch作用一样,都是协调线程进度的一个并发工具类。

它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

它们的不同之处:

1.CyclicBarrier可重用,CountdownLatch不可重用

2.在同一个线程中CountDownLatch可以多次CountDown(),当countDown到0的时候,一组线程中需要协调的地方即调用await()方法的地方阻塞消失,满足放行条件。而CyclicBarrier一个线程中最好调用一次await(),调用一次await()就相当于在栅栏处增加了一个线程,等满足条件后通过

3.countdowlatch是用在一组工作线程需要外部进行进度协调的地方,CyclicBarrier是用在一组工作线程相互之间需要协调进度的地方

CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。   CyclicBarrier        : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。


实例:

public class CyclicBarrierThread implements Runnable{

    private CyclicBarrier cyclicBarrier;

    CyclicBarrierThread(CyclicBarrier cyclicBarrier){
        this.cyclicBarrier=cyclicBarrier;
    }
    @Override
    public void run() {
        System.out.println("线程"+Thread.currentThread().getName()+"开始执行");
        Random random = new Random();
        if(random.nextBoolean()){
            try {
                Thread.sleep(3000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            //此处为一组线程组需要互相协调进度的地方,相当于一个栅栏,一个集合点
            System.out.println("线程"+Thread.currentThread().getName()+"集合点报道");
            cyclicBarrier.await();
            System.out.println("满足放行条件"+Thread.currentThread().getName()+"将通过栅栏");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

测试方法:

public static void main(String[] args){
        //3为此集合点需要达到的线程数量,才会放行。一个线程调用一次await(),相当于集合点多了一个线程
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        //启动三个线程
        for(int i=0;i<3;i++){
            new Thread(new CyclicBarrierThread(cyclicBarrier),"Thread_group1_"+i).start();
        }
        //休眠5秒保证第一组线程都通过集合点,然后启动线程组2
        try {
            Thread.sleep(5000l);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //再次启动三个线程,继续用同一个cyclicBarrier
        for(int i=0;i<3;i++){
            new Thread(new CyclicBarrierThread(cyclicBarrier),"Thread_group2_"+i).start();
        }

    }

运行结果:

线程Thread_group1_1开始执行
线程Thread_group1_0开始执行
线程Thread_group1_2开始执行
线程Thread_group1_1集合点报道
线程Thread_group1_0集合点报道
线程Thread_group1_2集合点报道
满足放行条件Thread_group1_2将通过栅栏
满足放行条件Thread_group1_0将通过栅栏
满足放行条件Thread_group1_1将通过栅栏
线程Thread_group2_0开始执行
线程Thread_group2_0集合点报道
线程Thread_group2_1开始执行
线程Thread_group2_1集合点报道
线程Thread_group2_2开始执行
线程Thread_group2_2集合点报道
满足放行条件Thread_group2_2将通过栅栏
满足放行条件Thread_group2_0将通过栅栏
满足放行条件Thread_group2_1将通过栅栏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值