【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
转载于:https://www.cnblogs.com/twoheads/p/9554645.html
【JUC】CountDownLatch相关推荐
- 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)
一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...
- 【JUC】第四章 JUC 辅助类、读写锁
第四章 JUC 辅助类.读写锁 文章目录 第四章 JUC 辅助类.读写锁 一.JUC 辅助类 1.减少计数 CountDownLatch 2.循环栅栏 CyclicBarrier 3.信号灯 Sema ...
- 【JUC】JDK1.8源码分析之ConcurrentHashMap
一.前言 最近几天忙着做点别的东西,今天终于有时间分析源码了,看源码感觉很爽,并且发现ConcurrentHashMap在JDK1.8版本与之前的版本在并发控制上存在很大的差别,很有必要进行认真的分析 ...
- 【JUC】第五章 JUC 阻塞队列、线程池
第五章 JUC 阻塞队列.线程池 文章目录 第五章 JUC 阻塞队列.线程池 一.阻塞队列 1.简介 2.BlockingQueue 的方法 3.常见的 BlockingQueue 二.线程池 1.简 ...
- 【JUC】第一章 JUC概述、Lock 接口
第一章 JUC 概述.Lock 接口 文章目录 第一章 JUC 概述.Lock 接口 一.JUC 概述 1.什么是 JUC 2.线程和进程概念 3.线程的状态 4.并发与并行 5.管程 6.用户线程和 ...
- 【多线程】CountDownLatch 和 CyclicBarrier:如何让多线程步调一致?
假设现在有一个对账系统,需要优化一下.它的基本业务是用户通过在线商城下单,然后生成电子订单,保存在订单库:之后物流会生成派送单给用户发货,派送单保存在派送单库.为了防止漏派送或重复派送,对账系统每天会 ...
- synchronousqueue场景_【JUC】JDK1.8源码分析之SynchronousQueue(九)
一.前言 本篇是在分析Executors源码时,发现JUC集合框架中的一个重要类没有分析,SynchronousQueue,该类在线程池中的作用是非常明显的,所以很有必要单独拿出来分析一番,这对于之后 ...
- 【JUC】动态线程池
一.背景 需求:动态调整参数.细粒度监控.秒级监控 线程池参数调优,需要不断的进行测试,判断内存占用等因素,调优没法热部署 别再纠结线程池大小了,没有固定公式 二.美团DynamicTp dynami ...
- 【多线程】CountDownLatch实现原理
前言 CountDownLatch是多线程中一个比较重要的概念,它可以使得一个或多个线程等待其他线程执行完毕之后再执行.它内部有一个计数器和一个阻塞队列,每当一个线程调用countDown()方法后, ...
最新文章
- Golang 标准库log的实现
- 实战渗透 | 向吃鸡外挂站开炮
- CMOS图像传感器——TDI CIS
- 企业实战_02_Redis基础
- 人类心理学中几乎没有人知道的东西是什么?
- SQL Server 2008 对 T-SQL 语言的增强(转载)
- Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
- android 代码操作.db demo,Android实现商品展示效果
- BT5的xprobe2的操作实例
- python环境下,PIP卸载、重装、升级
- 让读书的人面上有光:亚马逊Kindle青春版上市
- 仿生象鼻机械臂的创新设计与应用研究
- JAVA基础——循环结构(while)
- 设置笔记本为无线wifi发射器
- 数字转换成英语的程序(c++实现)
- android flurry 教程,Flurry没有集成到Android应用中
- 某内容管理系统最最最详细的代码审计
- Dango Web 开发指南 学习笔记 3
- python没有库怎么办_python缺少依赖(ImportError)库怎么办 | C/C++程序员之家
- 中移动收购米雷康姆在巴基斯坦子公司剩余股份
热门文章
- 解决VMWARE安装macos系统找不到虚拟磁盘问题
- __FUNCTION__, __FILE__, __LINE__ (原)
- Eigen入门之密集矩阵 7 - Map class:连接Eigen与C++的数据
- 【实例分割】cvpr2021_Look Closer to Segment Better
- 闪亮蔚蓝_在R中构建第一个闪亮的Web应用
- 欢迎使用CSDN-markdown编辑器1212131
- 数据管理 - 每天5分钟玩转 Docker 容器技术(147)
- 猪年看猪,猪男猪女一共十个。
- 使用vivado进行逻辑开发时,进行到Generate Bitstream时报错
- boa服务器怎样运行,boa服务器的配置与编译