• Java并发编程系列34:CountDownLatch使用


    CountDownLatch使用

    3.1、CountDownLatch介绍

    CountDownLatch(闭锁/门阀)是一个同步协助类,允许一个或多个线程等待,直到其他线程完成 操作集。

    1、CountDownLatch使用给定的计数值(count)初始化

    2、await阻塞等待

    3、countDown方法count--

    方法

    // 调用 await() 方法的线程会被挂起,等待直到 count 值为 0 才继续执行

    public void await() throws InterruptedException {

            sync.acquireSharedInterruptibly(1);

    }

    // 调用一次countDown()方法count值就会-1,当count值为0时,调用线程就能通过await()方法,恢复执行自己的任务

     public void countDown() { };

    await是阻塞,countDown是倒计,构造函数中指定初始值。只有初始值被countDown到0时,阻塞才会被打开所有等待的线程都会被释放。  count不会被重置(一次性现象). 这是和CyclicBarrier最大的区别。

    3.2、Demo示例

    主线程等待子线程都执行完才能执行。

    1. package runnable;
    2. import java.util.concurrent.CountDownLatch;
    3. import java.util.concurrent.LinkedBlockingQueue;
    4. import java.util.concurrent.ThreadPoolExecutor;
    5. import java.util.concurrent.TimeUnit;
    6. /**
    7. * ClassName CountDownLatchTest
    8. * description CountDownLatchTest
    9. *
    10. * @author : HMF
    11. * date: 2022/7/29 15:42
    12. **/
    13. public class CountDownLatchTest {
    14. public static void main(String[] args){
    15. int RUNNER_COUNT=5;
    16. CountDownLatch latch = new CountDownLatch(RUNNER_COUNT);
    17. ThreadPoolExecutor exs=new ThreadPoolExecutor(5,10,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
    18. for (int i=0;i
    19. exs.execute(new Runnable01(latch));
    20. }
    21. exs.shutdown();
    22. try {
    23. latch.await(); //必须等待计数器count等于0,等于0之后,主线程执行
    24. } catch (InterruptedException e) {
    25. e.printStackTrace();
    26. }
    27. System.out.println("主线程执行");
    28. }
    29. static class Runnable01 implements Runnable{
    30. private CountDownLatch latch;
    31. public Runnable01(CountDownLatch latch){
    32. this.latch=latch;
    33. }
    34. @Override
    35. public void run() {
    36. System.out.println("子线程执行,线程名称:"+Thread.currentThread().getName());
    37. latch.countDown(); //计数器count-1
    38. }
    39. }
    40. }

    执行结果:

    3.3、CyclicBarrier和CountDownLatch区别

    1、CountDownLatch的await()线程会等待计数器减为0,而执行CyclicBarrier的await()方法会使线程进入阻塞等待其他线程到达障点。

    2、CountDownLatch计数器不能重置,CyclicBarrier可以重置循环利用。

    3、CountDownLatch是基于AQS的共享模式实现的,CyclicBarrier是基于ReentrantLock和Condition实现的。

    一个是利用AQS获取status值,另一种是通过ReentrantLock的唤醒机制来实现。

    备注:

    CountDownLatch侧重于一个或者多个线程等待其他线程中执行的操作完成。应用场景如:背景想要获取用户最大的数据集合(用户基本数据、订单、购物车信息),但是用户基本数据、订单、购物车信息都在不同的微服务中,这种情况可以使用,主线程在获取基本数据的同时,将订单信息、购物信息另开线程异步获取,最终主线程会等待其他线程获取的消息进行合集返回(例如老师等待学生考完试后收试卷,适合任务A执行完后再执行任务B)

    CyclicBarrier更加侧重:所有的线程都在await()的,等待最后一个计数之后,所有的线程统一执行(例如:栅栏拦住跑者,等待所有人(线程)到达后一起去跑(执行),适合压测)

    CountDownLatch来说,重点是“一个线程等待(多个线程)”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须互相等待,然后继续一起执行

    参考:https://www.jianshu.com/p/3c6315b4923b

    https://www.jianshu.com/p/d593dea9172d

     

  • 相关阅读:
    magma build system 分析 —— 第04记 make -n 的记录
    @Cacheable 、 @CachePut 、@CacheEvict 注解
    16G DWDM SFP+光模块特性及解决方案
    如何使用 WPF 应用程序连接 FastReport报表
    【经验分享】突然我的SM.MS的图床没法访问了(内附解决方法)
    信息学奥赛一本通 1617:转圈游戏 | 1875:【13NOIP提高组】转圈游戏 | 洛谷 P1965 [NOIP2013 提高组] 转圈游戏
    第33讲:MySQL存储引擎的介绍和基本应用
    2022年最新《谷粒学院开发教程》:6 - 整合SpringCloud
    Flask g对象和插件
    使用imx 8m 测试matter协议功能
  • 原文地址:https://blog.csdn.net/fen_fen/article/details/126060879