JUC并发工具类之 CountDownLatch等待多线程完成
上篇JUC同步工具之Semaphore - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)示例中,资源释放一个线程就可以退出然后另一个线程可以使用了,那如果需要所有规定数量的资源同时释放了才可以退出,那如何实现同步呢?CountDownLatch。

从UML图中可以知道,CountDownLatch原理和Semaphore原理类似,同样是基于AQS,不过没有公平和非公平之分。
假设一个主线程要等待5个 Worker 线程执行完才能退出,看看使用CountDownLatch如何实现:



从上三图中的红框部分测试结果,通过CountDownLatch中的countDown和await方法共同作用实现了同步等待。具体如何实现呢?请看下面分析:
1、与Semaphore相似,CountDownLatch使用AQS的同步状态持有当期的计数:

2、await()实现分析:

CountDownLatch重写ryAcquireShared,从tryAcquireShared(...)方法的实现来看,只要state != 0,调用await()方法的线程便会被放入AQS的阻塞队列,进入阻塞状态,反之如果计数器已经到达零,会立即返回。
2、countDown()实现分析:

countDown()调用的AQS的模板方法releaseShared(),里面的tryReleaseShared(...)由CountDownLatch.Sync实现。从上面的代码可以看出,只有state=0,tryReleaseShared(...)才会返回true,然后执行doReleaseShared(...),一次性唤醒队列中所有阻塞的线程。
由于是基于AQS阻塞队列来实现的,所以可以让多个线程都阻塞在state=0条件上,通过countDown()一直减state,减到0后一次性唤醒所有线程。
JUC并发工具类之 CountDownLatch等待多线程完成的更多相关文章
- juc并发工具类之CountDownLatch闭锁
import java.util.concurrent.CountDownLatch; /** * 闭锁: 在进行某些运算时, 只有其他所有线程的运算全部完成,当前运算才继续执行(程序流中加了一道栅栏 ...
- 并发工具类:CountDownLatch、CyclicBarrier、Semaphore
在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch ...
- 【Java并发工具类】CountDownLatch和CyclicBarrier
前言 下面介绍协调让多线程步调一致的两个工具类:CountDownLatch和CyclicBarrier. CountDownLatch和CyclicBarrier的用途介绍 CountDownLat ...
- j.u.c系列(08)---之并发工具类:CountDownLatch
写在前面 CountDownLatch所描述的是”在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待“:用给定的计数 初始化 CountDownLatch.由于调用了 countDo ...
- 线程并发工具类之CountDownLatch的使用及原理分析
原文链接:http://www.studyshare.cn/blog/details/1149/1 java开发工具下载地址及安装教程大全,点这里.更多技术文章,在这里. 一.定义 CountDown ...
- Java中的并发工具类:CountDownLatch、CyclicBarrier和Semaphore
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 一. ...
- JUC并发工具类
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11449367.html java.util.concurrent及其子包,集中了Java并发的各种基础 ...
- 多线程进阶之并发工具类:CountDownLatch、CyclicBarrier
并发工具类在java.util.concurrent包下.常用的有CountDownLatch.CyclicBarrier,用它们可以控制并发流程. 1.CountDownLatch探究: 主要用到其 ...
- Java并发工具类之CountDownLatch
CountDownLatch允许一个或则多个线程等待其他线程完成操作. 假如我们有这样的需求:我们需要解析一个excel文件中的多个sheet,我们可以考虑使用多线程,每一个线程解析excel中的一个 ...
随机推荐
- SpringCloud的Config应用
一.简介 ***应用程序先注册到注册中心,在注册中心根据guli-config服务的名字找到配置中心,然后在配置中心根据配置从github加载基本配置. 二.配置中心(服务端,可以部署集群) 1.依赖 ...
- POJ 2456 Aggressive cows(贪心 + 二分)
原题链接:Aggressive cows 题目大意:农夫 建造了一座很长的畜栏,它包括 个隔间,这些小隔间依次编号为. 但是, 的 头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争 ...
- 2022 跳槽涨薪必不可少面试通关宝典 —— css 篇
生于忧患死于安乐!已经居家隔离 23 天了,解封以后估计就得找工作了,提前准备起来!需要的赶紧收藏起来 一.谈谈你对 BFC 的理解及作用. BFC 是 Block Formatting Contex ...
- Exception in thread “main“ java.net.ConnectException: Call From
问题描述:#报错语句:FileSystem fs = FileSystem.get(new URI("hdfs://hadoop000:8020"),new Configurati ...
- 【记录一个问题】thanos receiver在tsdb切换期间,导致remote write接口失败增加
如图:配置了thanos receiver落盘的时间周期为10分钟,结果导致在切换tsdb期间,remote write接口的失败率增高. 目前看来,解决办法就是上游增加重试.
- 【必杀】为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误。该进程 ID 为“XXXX”。数据字段包含错误号。
之前写过一篇文章,https://www.cnblogs.com/qidian10/p/6028784.html 解释如何解决此类问题,但现在回过头来想一下,之前的文章还是太过浅显,无法完全有效的彻底 ...
- springMvc 启动过程
转载自https://www.jianshu.com/p/dc64d02e49ac 这里给出一个简洁的文字描述版SpringMVC启动过程: tomcat web容器启动时会去读取web.xml这样的 ...
- golang中的配置管理库viper
viper简介 Viper是适用于Go应用程序的完整配置解决方案.它旨在在应用程序中工作,并且可以处理所有类型的配置需求和格式.它支持: 设置默认值 从JSON,TOML,YAML,HCL,envfi ...
- golang中的标准库time
时间类型 time.Time类型表示时间.我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息.示例代码如下: func main() { current := ...
- gin中HTML渲染
package main import ( "github.com/gin-gonic/gin" "net/http" ) func login(ctx *gi ...