因为在调用端的异步中,需要调用其他多个服务获取数据再汇总结果返回,所以用到了CountDownLatch

CountDownLatch的概念

CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。

CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成了任务,然后在CountDownLatch上等待的线程就可以恢复执行任务。

CountDownLatch的用法

CountDownLatch典型用法1:某一线程在开始运行前等待n个线程执行完毕。将CountDownLatch的计数器初始化为n new CountDownLatch(n) ,每当一个任务线程执行完毕,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await() 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。

CountDownLatch典型用法2:实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的CountDownLatch(1),将其计数器初始化为1,多个线程在开始执行任务前首先 coundownlatch.await(),当主线程调用 countDown() 时,计数器变为0,多个线程同时被唤醒。

CountDownLatch的不足

CountDownLatch是一次性的,计数器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后,它不能再次被使用。

CountDownLatch使用案例

需求:解析一个文件下多个txt文件数据,可以考虑使用多线程并行解析以提高解析效率。每一个线程解析一个文件里的数据,等到所有数据解析完毕之后再进行其他操作。

设计分析:在这个需求中,需要实现主线程等待所有线程完成文件解析操作,CountDownLatch正好可以做到。

CountDownLatch源码分析

CountDownLatch是自定义AQS同步组件,是AQS的一个非常简单的实现,接下来就以自定义同步器Sync、countDown方法和await方法为切入点,分析CountDownLatch的具体实现。

  • 自定义同步器Sync实现[sɪŋk]

    自定义同步器实现

    同步器Sync实现了共享式获取同步状态的acquire和release,前文中已经详细介绍过AQS相关内容,在这里我就不再做详细介绍分析了。

  • 构造方法

    构造方法

    从构造方法的具体实现可以看出,通过构造方法传入的int型参数count其实就是同步器的状态State。

  • countDown实现

    countDown实现

    整个countDown只做了一件事情,释放同步状态,同步状态在这里的实际意义也就是需要等待的完成的点的数量,只要每完成一个点,就调用countDown方法释放同步状态。

  • await实现
    CountDownLatch提供带超时时间的await和不带超时时间的await:

    await实现

    await的实质是在获取同步状态,同步状态state == 0成立,当前等待完成的点均已完成,主线程继续往下执行,否则,主线程进入等待队列自旋等待直到同步状态释放后state == 0。有些时候主线程是不能一直自旋等待,这个时候带超时时间的await就派上用场了,设置超时时间,如果在指定时间内N个点都未完成,返回false,主线程不再等待,继续往下执行。

参考AQS结构图方便理解:

总结:CountDownLatch实质上就是一个AQS计数器,通过AQS来实现线程的等待与唤醒。

链接:https://www.jianshu.com/p/bce9f156080f

https://blog.csdn.net/joenqc/article/details/76794356

转载于:https://www.cnblogs.com/twoheads/p/9554645.html

【JUC】CountDownLatch相关推荐

  1. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  2. 【JUC】第四章 JUC 辅助类、读写锁

    第四章 JUC 辅助类.读写锁 文章目录 第四章 JUC 辅助类.读写锁 一.JUC 辅助类 1.减少计数 CountDownLatch 2.循环栅栏 CyclicBarrier 3.信号灯 Sema ...

  3. 【JUC】JDK1.8源码分析之ConcurrentHashMap

    一.前言 最近几天忙着做点别的东西,今天终于有时间分析源码了,看源码感觉很爽,并且发现ConcurrentHashMap在JDK1.8版本与之前的版本在并发控制上存在很大的差别,很有必要进行认真的分析 ...

  4. 【JUC】第五章 JUC 阻塞队列、线程池

    第五章 JUC 阻塞队列.线程池 文章目录 第五章 JUC 阻塞队列.线程池 一.阻塞队列 1.简介 2.BlockingQueue 的方法 3.常见的 BlockingQueue 二.线程池 1.简 ...

  5. 【JUC】第一章 JUC概述、Lock 接口

    第一章 JUC 概述.Lock 接口 文章目录 第一章 JUC 概述.Lock 接口 一.JUC 概述 1.什么是 JUC 2.线程和进程概念 3.线程的状态 4.并发与并行 5.管程 6.用户线程和 ...

  6. 【多线程】CountDownLatch 和 CyclicBarrier:如何让多线程步调一致?

    假设现在有一个对账系统,需要优化一下.它的基本业务是用户通过在线商城下单,然后生成电子订单,保存在订单库:之后物流会生成派送单给用户发货,派送单保存在派送单库.为了防止漏派送或重复派送,对账系统每天会 ...

  7. synchronousqueue场景_【JUC】JDK1.8源码分析之SynchronousQueue(九)

    一.前言 本篇是在分析Executors源码时,发现JUC集合框架中的一个重要类没有分析,SynchronousQueue,该类在线程池中的作用是非常明显的,所以很有必要单独拿出来分析一番,这对于之后 ...

  8. 【JUC】动态线程池

    一.背景 需求:动态调整参数.细粒度监控.秒级监控 线程池参数调优,需要不断的进行测试,判断内存占用等因素,调优没法热部署 别再纠结线程池大小了,没有固定公式 二.美团DynamicTp dynami ...

  9. 【多线程】CountDownLatch实现原理

    前言 CountDownLatch是多线程中一个比较重要的概念,它可以使得一个或多个线程等待其他线程执行完毕之后再执行.它内部有一个计数器和一个阻塞队列,每当一个线程调用countDown()方法后, ...

最新文章

  1. Golang 标准库log的实现
  2. 实战渗透 | 向吃鸡外挂站开炮
  3. CMOS图像传感器——TDI CIS
  4. 企业实战_02_Redis基础
  5. 人类心理学中几乎没有人知道的东西是什么?
  6. SQL Server 2008 对 T-SQL 语言的增强(转载)
  7. Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
  8. android 代码操作.db demo,Android实现商品展示效果
  9. BT5的xprobe2的操作实例
  10. python环境下,PIP卸载、重装、升级
  11. 让读书的人面上有光:亚马逊Kindle青春版上市
  12. 仿生象鼻机械臂的创新设计与应用研究
  13. JAVA基础——循环结构(while)
  14. 设置笔记本为无线wifi发射器
  15. 数字转换成英语的程序(c++实现)
  16. android flurry 教程,Flurry没有集成到Android应用中
  17. 某内容管理系统最最最详细的代码审计
  18. Dango Web 开发指南 学习笔记 3
  19. python没有库怎么办_python缺少依赖(ImportError)库怎么办 | C/C++程序员之家
  20. 中移动收购米雷康姆在巴基斯坦子公司剩余股份

热门文章

  1. 解决VMWARE安装macos系统找不到虚拟磁盘问题
  2. __FUNCTION__, __FILE__, __LINE__ (原)
  3. Eigen入门之密集矩阵 7 - Map class:连接Eigen与C++的数据
  4. 【实例分割】cvpr2021_Look Closer to Segment Better
  5. 闪亮蔚蓝_在R中构建第一个闪亮的Web应用
  6. 欢迎使用CSDN-markdown编辑器1212131
  7. 数据管理 - 每天5分钟玩转 Docker 容器技术(147)
  8. 猪年看猪,猪男猪女一共十个。
  9. 使用vivado进行逻辑开发时,进行到Generate Bitstream时报错
  10. boa服务器怎样运行,boa服务器的配置与编译