首页 > 编程语言 > 详细

java并发(二)--CountDownLatch|CyclicBarrier

时间:2020-12-08 09:34:03      阅读:42      评论:0      收藏:0      [点我收藏+]

info

CountDownLatch和CyclicBarrier支持在java中较为简单的线程编排,通过单个线程的阻塞来获取其他异步线程的结果。
较为常见的场景为主线程阻塞来获取子线程并行计算产生结果,用于之后的运算。
两者区别:

  1. CountDownLatch不支持循环计数,CyclicBarrier支持循环计数
  2. CyclicBarrier的计数器由自己控制,而CountDownLatch的计数器则由使用者来控制
  3. 内部实现是原理不一致,CountDownLatch使用AQS共享模式,CyclicBarrier采用较传统的lock+condition模式

code

CountDownLatch

CountDownLatch表示的是多个线程执行过程中的一种状态,状态是会发生变化的。不通时间去调用getCount()获取到的结果是不一样的,表示还有多少信号量遗留。

public class TestCountDownLunch {
    
    public static void main(String[] args) throws Exception {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for(int i = 0;i<1;i++){
                    if(i%1000000 == 0) {
                        System.out.println("第一个线程" + i);
                    }
                }
                //信号量减一
                countDownLatch.countDown();
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for(int i = 0;i<1;i++){
                    if(i%990000 == 0) {
                        System.out.println("第二个线程" + i);
                    }
                }
                //信号量减一
                countDownLatch.countDown();
            }
        };
        t1.start();
        t2.start();
        //等待信号量减到0的时候,主线程继续执行(支持最长等待时间)
        countDownLatch.await(10, TimeUnit.SECONDS);
        for(int i = 0;i<10;i++){
            System.out.println("主线程"+i);
        }
    }
}

CyclicBarrier

CyclicBarrier表示的是多个线程执行过程中的一种状态,Barrier代表一次阻塞,状态是会发生变化的。底层使用是 ReentrantLock 和 Condition 的组合使用。
支持检查当先阻塞状态是否被打破(是否有线程被中断)isBroken(),当信号量==0、有线程超时触发异常、有线程被中断触发异常(BrokenBarrierException),都会导致阻塞被打破。
阻塞被打破之后,所有其他线程会被唤醒。

public class TestCycilcBarrier {

    public static void main(String[] args) throws Exception {
        //满足信号量==0的时候,自动触发回调函数
        //信号量减到0之后,能够恢复到初始值2(差异点)
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2,() -> callBack());
        for(int j = 0;j<2;j++) {
            Thread t1 = new Thread(() -> {
                for (int i = 0; i < 100000000; i++) {
                    if (i % 1000000 == 0) {
                        System.out.println("第一个线程" + i);
                    }
                }
                try {
                    //信号量减一
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            Thread t2 = new Thread(() -> {
                for (int i = 0; i < 100000000; i++) {
                    if (i % 990000 == 0) {
                        System.out.println("第二个线程" + i);
                    }
                }
                try {
                    //信号量减一
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            t1.start();
            t2.start();
        }
    }
    static void callBack() {
        System.out.println("callBack");
    }
}

参考文章:https://blog.csdn.net/qq_39241239/article/details/87030142

java并发(二)--CountDownLatch|CyclicBarrier

原文:https://www.cnblogs.com/ElliottX4/p/14100481.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!