【JUC】CountDownLatch
因为在调用端的异步中,需要调用其他多个服务获取数据再汇总结果返回,所以用到了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
【JUC】CountDownLatch的更多相关文章
- 【JUC】CountDownLatch和Java枚举的使用例子
public enum CountryEnum { ONE(1,"春"), TWO(2,"夏"), THREE(3,"秋"), FOUR(4 ...
- 【1】【JUC】JDK1.8源码分析之ReentrantLock
概要: ReentrantLock类内部总共存在Sync.NonfairSync.FairSync三个类,NonfairSync与FairSync类继承自Sync类,Sync类继承自AbstractQ ...
- 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)
一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...
- 【1】【JUC】JDK1.8源码分析之ArrayBlockingQueue,LinkedBlockingQueue
概要: ArrayBlockingQueue的内部是通过一个可重入锁ReentrantLock和两个Condition条件对象来实现阻塞 注意这两个Condition即ReentrantLock的Co ...
- 【JUC】阻塞队列&生产者和消费者
阻塞队列 线程1往阻塞队列添加元素[生产者] 线程2从阻塞队列取出元素[消费者] 当队列空时,获取元素的操作会被阻塞 当队列满时,添加元素的操作会被阻塞 阻塞队列的优势:在多线程领域,发生阻塞时,线程 ...
- 【JUC】JDK1.8源码分析之CountDownLatch(五)
一.前言 分析完了CyclicBarrier后,下面分析CountDownLatch,CountDownLatch用于同步一个或多个任务,强制他们等待由其他任务执行的一组操作完成.CountDownL ...
- 【JUC】7.CountDownLatch
Latch:门闩.一种线程通信的方式:当程序不涉及同步,仅仅需要线程通信的时候,使用synchronize或者lock的线程通信等待唤醒机制,就显得太重了: 这时候,可以考虑使用信号量类:CountD ...
- 【JUC】JUC锁框架综述
一.前言 在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程.我们分为几个模块进行分析,首先是 ...
- 【1】【JUC】Condition和生产者消费者模型
本篇文章将介绍Condition的实现原理和基本使用方法,基本过程如下: 1.Condition提供了await()方法将当前线程阻塞,并提供signal()方法支持另外一个线程将已经阻塞的线程唤醒. ...
随机推荐
- Windows10 RedStone 1使用Bash体验
很多年前,记得在Windows Server2008的Feature里发现了Windows Subsystem For Unix,当时也不知道干啥用的,还以为是Samba协议用的呢. 今天,发现Win ...
- OSI的七层模型介绍
应用层: 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层: 数据格式化,代码转换,数据加密 没有协议. (信息的语法语义以及它们的 ...
- [转帖]召冠总的 SQLSERVER常用的性能诊断语句. --保存学习备查
CopyFrom https://www.cnblogs.com/zhaoguan_wang /*常规服务器动态管理对象包括:dm_db_*:数据库和数据库对象dm_exec_*:执行用户代码和关联的 ...
- SAP PA认证
----------------------------------------------------------------转帖---------------------------------- ...
- (二) 关于配置travis-ci持续集成python pytest测试的相关记录
接上篇 上篇只是非常官方的描述了一下travis-ci是包括了些什么部分会如何工作但是并没有深入介绍也没有写demo. 这里先贴上一个我已经测试好了的python_travis-ci的环境 https ...
- schema举例一
schema举例一: <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs=& ...
- python之input()、while、title()和upper()
代码举例: # 小应用:问卷调查,记录下调查者名字和回答,询问是否继续. # 运用数据字典.while.input().title()和upper(). responses = {} flag = T ...
- MT【216】韦达定理
设$n$为正整数,$a_1,a_2,\cdots,a_n;b_1,b_2,\cdots,b_n;A,B$都是正数, 满足$a_i\le b_i,a_i\le A,i=1,2,\cdots,n$ 且$\ ...
- Mac 下重新安装配置ibm Lotus 邮箱
若邮箱之前有人使用,需要重新安装.在卸载程序之后,发现仍旧无法重新配置新的账号. 此时需要删除用户目录下的2个文件: /Library/Application Support/IBM Notes Da ...
- Python Matplot中文显示完美解决方案
原因与现象 Matplot是一个功能强大的Python图表绘制库,很遗憾目前版本自带的字体库中并不支持中文字体.所以如果在绘制内容中需要显示中文,那么就会显示为方格字符. 解决办法 有一个较为完美的解 ...