【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()方法支持另外一个线程将已经阻塞的线程唤醒. ...
随机推荐
- Sub-Processes and Call Activities
https://www.activiti.org/userguide/#bpmnCallActivity http://www.flowable.org/docs/userguide/index.ht ...
- oracle11.2.0.1 deferred_segment_creation 造成exp imp 空表无法导出的问题
oracle11g 新增加了 deferred_segment_creation 的属性在创建的数据库表中,如果表中没有数据,并且这个参数是true的话,并不是直接就在数据文件中的增加相应的segm ...
- 转帖: 一份超全超详细的 ADB 用法大全
增加一句 连接 网易mumu模拟器的方法 adb connect 127.0.0.1:7555 一份超全超详细的 ADB 用法大全 2016年08月28日 10:49:41 阅读数:35890 原文 ...
- 手动安装ettercap的过程
知乎推送了一个中间人攻击的软件 ettercap 想着尝试进行一下安装学习, 如果有机会的话安全测试部分应该用的到. 1. 下载: wget https://codeload.github.com/E ...
- zlib 简单封装
下列代码用于压缩和解压字符串,使用标准库string.实现了对zlib的简单封装. #pragma once #include <boost/noncopyable.hpp> #inclu ...
- 暂时刷完leetcode的一点小体会
两年前,在实习生笔试的时候,笔试百度,对试卷上很多问题感到不知所云,毫无悬念的挂了 读研两年,今年代笔百度,发现算法题都见过,或者有思路,但一时之间居然都想不到很好的解法,而且很少手写思路,手写代码, ...
- js 消息框
消息框有三種:警告框.提示框.確認框 警告框: 確保用戶可以得到某些信息. 點擊確定以後,才能繼續後續操作. alert("不好") 確認框: 請用戶確認或者接受某些信息. 點擊確 ...
- Java之JSON处理(JSONObject、JSONArray)
依赖包:json-20180130.jar MAVEN地址: <dependency> <groupId>org.json</groupId> <artifa ...
- python 从filelist.txt中拷贝文件到另一文件夹中
#! python #coding:utf-8 ##!/usr/bin/python # Filename : fileCp.py import sys import os import shutil ...
- Django-website 程序案例系列-1 最简单的web服务器
templates:html模板文件夹下面建立文件login.html <!DOCTYPE html> <html lang="en"> <head& ...