CountDownLatch深度剖析
- 场景引入
日常开发中,有个需求,要求主线程开启多个线程去并行执行任务,并且主线程需要等待所有的子线程执行完成后进行汇总。我们很容易找到 jion()方法来实现这个功能

缺点:由于工作中,我们不会直接创建线程,一般都是交给线程池处理,那么我们就没法对线程池里的线程调用join()方法了。
2.需求升级
主线程不必等所有的子线程全部执行完成就可以进行汇总,并且子线程还能执行其他的无关的功能。查阅JUC包,我们发现CountDownLatch、CyclicBarrier、Semaphore均可以实现这个功能。
今天我们主要学习一下CountDownLatch

3. join 和 CountDownLatch比较
- 调用一个子线程的join()方法后,该线程(主线程)会一直被阻塞,直到子线程运行完成。而CountDownLatch使用计数器,在调用countDown()方法递减计数,在计数器为0时,唤醒阻塞的线程,而不必等到子线程执行完成。
- 在使用线程池执行任务时,join()方法不能使用,CountDownLatch的使用更加灵活。
4. 源码走读
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
// 底层是AQS,构造函数的入参传递给AQS的state属性
this.sync = new CountDownLatch.Sync(count);
}
// 调用该方法,计数器的值递减,当计数器的值为0则唤醒所有因调用该方法而阻塞的线程,
//否则什么也不做
public void countDown() {
// 委托sync调用AQS的方法
sync.releaseShared(1);
} public final boolean releaseShared(int arg) {
// 调用sync实现的tryReleaseShared方法
if (tryReleaseShared(arg)) {
// AQS的释放资源方法,唤醒由于调用await方法而阻塞的线程,此时阻塞线程往下执行,但是不影响子线程调用countDown方法后面的代码的继续执行
doReleaseShared();
return true;
}
return false;
}
protected boolean tryReleaseShared(int releases) {
// 循环进行cas,直到当前线程成功完成计数器减一并更新到state
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c - 1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
// 判断state是否为0
if (tryAcquireShared(arg) < 0)
// 如果不为0,则将当前线程加入到AQS的队列等待
doAcquireSharedInterruptibly(arg);
}
// 单纯的判断AQS的state是否为0
protected int tryAcquireShared(int acquires) {do
return (getState() == 0) ? 1 : -1;
}
5. 总结
CountDownLatch基于AQS实现(CountDownLatch静态内部类Sync)。使用AQS的状态值state来存放计数器的值。首先在初始化的时候,设置状态值(计数器的值),当多个线程调用countDown()方法时,实际上是对AQS进行原子性递减。当有线程调用await()方法时后,该线程会被放入AQS的阻塞队列等待计数器为0再返回。其他线程调用 countDown 方法让计数器值递减1,当计数器的值变为0时,当前线程还要调用AQS的 doReleaseShared 方法来激活由于调用 await 方法而阻塞的线程。
CountDownLatch深度剖析的更多相关文章
- 《AngularJS深度剖析与最佳实践》简介
由于年末将至,前阵子一直忙于工作的事务,不得已暂停了微信订阅号的更新,我将会在后续的时间里尽快的继续为大家推送更多的博文.毕竟一个人的力量微薄,精力有限,希望大家能理解,仍然能一如既往的关注和支持sh ...
- ASP.NET Core管道深度剖析(2):创建一个“迷你版”的管道来模拟真实管道请求处理流程
从<ASP.NET Core管道深度剖析(1):采用管道处理HTTP请求>我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但 ...
- Objective-C类成员变量深度剖析
目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...
- 大众点评开源分布式监控平台 CAT 深度剖析
一.CAT介绍 CAT系统原型和理念来源于eBay的CAL的系统,CAT系统第一代设计者吴其敏在eBay工作长达十几年,对CAL系统有深刻的理解.CAT不仅增强了CAL系统核心模型,还添加了更丰富的报 ...
- 深度剖析WordPress主题结构(转)
利用强大的技术,可以把基于wordpress的网站做成各种各样的形式,这除了要求wordpress主题开发人员精通html,PHP,JS,CSS等技术,还需要开发者掌握WordPress主题的框架. ...
- LCD深度剖析
LCD 深度剖析 来源:http://blog.csdn.net/hardy_2009/article/details/6922900 http://blog.csdn.net/jaylondon/a ...
- WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(下篇)
原文:WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(下篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话 ...
- 大兴雷克萨斯深度剖析2013款LS460L_深圳大兴雷克萨斯_太平洋汽车网
大兴雷克萨斯深度剖析2013款LS460L_深圳大兴雷克萨斯_太平洋汽车网 大兴雷克萨斯深度剖析2013款LS460L
- Java反射机制剖析(四)-深度剖析动态代理原理及总结
动态代理类原理(示例代码参见java反射机制剖析(三)) a) 理解上面的动态代理示例流程 a) 理解上面的动态代理示例流程 b) 代理接口实现类源代码剖析 咱们一起来剖析一下代理实现类($Pr ...
随机推荐
- Java基础教程——File类、Paths类、Files类
File类 File类在java.io包中.io代表input和output,输入和输出. 代表与平台无关的文件和目录. 可以新建.删除.重命名,但不能访问文件内容. File类里的常量: impor ...
- 第一次个人作业 - 软件工程与UML
这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1/ 这个作业要求在哪里 https://edu.cnblogs.com/campus/f ...
- JZOJ 11.21 提高B组反思
JZOJ 11.21 提高B组反思 T1 第二类斯特林数 直接套公式 \(S(i,j)=S(i-1,j-1)+S(i-1,j)*j\) 由于过大,\(unsigned\ long\ long\)都存不 ...
- 关于Django的序列化问题。serializers
在DRF框架里,ModelSerializers是一个重要的组件.大大的帮组我们节省了数据序列化的过程,真的可以说是良心产品.接手的这个项目用的Django,前人的代码都是手动序列化的,为了保证风格的 ...
- 微服务注册到Nacos的IP私网172.x.x.x网段无法访问的问题
解决方案一 显示声明注册服务实例的外网IP,默认就是使用私网的IP造成无法访问的,配置如下: spring: cloud: nacos: discovery: ip: 101.37.6.8 解决方案二 ...
- moviepy音视频开发:音频剪辑基类AudioClip
☞ ░ 前往老猿Python博文目录 ░ 一.背景知识介绍 1.1.声音三要素: 音调:人耳对声音高低的感觉称为音调(也叫音频).音调主要与声波的频率有关.声波的频率高,则音调也高. 音量:也就是响度 ...
- moviepy音视频剪辑:使用concatenate_videoclips和clips_array将多个视频合成一个顺序播放或同屏播放的视频
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.视频合成概述 视频合成,也称为非线性编辑,实际 ...
- WindowsServer系统设置U盘引导及安装
准备一台服务器,我的服务器上图. 1.开机启动,按DEL进入BIOS.我的显示如下图,按F7进入. 2.找到设置启动项的地方 3.修改U盘启动项 4.保存退出. 5.重启服务器正常的话应该能够从U盘引 ...
- XDown单文件版 下载工具 支持磁力等多种链接方式下载
原来的程序不带剪辑板探测,不支持迅雷链接等 增加功能后优化制作单文件版本. 下载类型为下图 magnet:?xt=urn:btih:836A228D932EF1C7EA1DD99D5D80B7CB0C ...
- 深入理解Java虚拟机(八)——类加载机制
是什么是类加载机制 Java虚拟机将class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程就是类加载机制. 类的生命周期 一个类从加载到内存 ...