• CyclicBarrier和CountDownLatch


    CyclicBarrier:

    用于协调多个线程同步执行的操作场合,所有线程等待完成,然后一起执行
    使用方式:
    CyclicBarrier barrier = new CyclicBarrier(3);
    定义初始数量,线程数必须达到才能执行
    代码示例:

       public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3);
        new Thread(()->{
            try {
                Thread.sleep(1000);
                System.out.println("1就位"+barrier.getNumberWaiting());
                barrier.await();
                System.out.println("1开始执行");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
        }).start();
        new Thread(()->{
            try {
                Thread.sleep(3000);
                System.out.println("2就位"+barrier.getNumberWaiting());
                barrier.await();
                System.out.println("2开始执行");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
        }).start();
    
        System.out.println("主程序就位"+barrier.getNumberWaiting());
        try {
            barrier.await();  //在CyclicBarrier上进行阻塞等待
            System.out.println("主程序开始");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (BrokenBarrierException e) {
            throw new RuntimeException(e);
        }
        try {
            /**
             * 不执行完毕重置会报错
             */
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("重置前:"+barrier.getNumberWaiting());  //获取当前有多少个线程阻塞等待在临界点上
        barrier.reset();  //使得CyclicBarrier回归初始状态
        System.out.println("重置后:"+barrier.getParties());  //获取CyclicBarrier打开屏障的线程数量
    
    }
    isBroken()  //获取是否破损标志位broken的值
    await(timeout,TimeUnit) //配置后,如果阻塞数量达不到指定数量是,在指定时间超出是执行
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    可以看出运行结果,当线程数达到3个barrier.await()时才会执行相关程序 barrier.await()以下的相关代码

    在这里插入图片描述

    CountDownLatch:

    用于一个或者一组线程在开始执行操作之前,必须要等到其他线程执行完才可以
    代码示例

    public static void main(String[] args) {
            CountDownLatch downLatch = new CountDownLatch(3);  //初始化容量
            new Thread(()->{
                try {
                    Thread.sleep(1000);
                    downLatch.countDown();
                    System.out.println("1开始执行"+downLatch.getCount());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }).start();
    
             new Thread(()->{
                try {
                    Thread.sleep(2000);
                    downLatch.countDown();
                    System.out.println("2开始执行"+downLatch.getCount());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }).start();
    
            new Thread(()->{
                try {
                    Thread.sleep(3000);
                    downLatch.countDown();  //初始量减1
                    System.out.println("3开始执行"+downLatch.getCount());  //获取剩余数量
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }).start();
    
            try {
                downLatch.await(5,TimeUnit.SECONDS);  //此处跟上面定义一样,如果不足初始量,阻塞超时,继续执行
    //           downLatch. await(long timeout, TimeUnit unit)  #可以设置等待时间,时间到了不管有没有达到数量,也要执行
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
    
            System.out.println("执行完成:"+downLatch.getCount());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述
    三个线程执行完成过后才执行主线程

    总结:

    CyclicBarrier:
        1,可以循环使用
        2,工作线程之间必须等到同一个点才能执行
    CountDownLatch:
        1,CountDownLatch不能reset
        2,工作线程之间彼此互不关心

  • 相关阅读:
    shell编程基础
    两客一危解决方案-最新全套文件
    免费的VMware ?就是它了!【送源码】
    Android编译系统apk并进行系统签名安装
    Apache Inlong:数据集成框架原理及实践
    [SpringBoot]SpringBoot整合第三方技术
    园子开店记:被智能的淘宝处罚,说是“预防性的违规”
    Ubuntu 22.04 进入救援或单用户模式-Ubuntu 22.04忘记root密码
    华为云云耀云服务器L实例评测|redis漏洞回顾 & MySQL数据安全解决 搭建主从集群MySQL & 相关设置
    thymeleaf,bootstrap-fileinput 多文件上传
  • 原文地址:https://blog.csdn.net/qq_27950699/article/details/132724828