2019独角兽企业重金招聘Python工程师标准>>>

1、 应用场景

  CountDownLatch是并发包中用来控制一个或者多个线程等待其他线程完成操作的并发工具类。现以工作中的一个场景来描述下CountDownLatch的应用,代码如下:

/*模拟工作中的一个需求场景:
用户会选择多个算法来计算费用,最后会将所有算法计算出的费用做一个加权求平均数,这个平均数是最终的费用。
每个算法的复杂度都不一样,打算每个线程负责一个算法的实现,所有的线程执行完成,最后再求平均数。
1、为每个算法创建一个线程,每个线程负责一个算法的实现
2、通过CountDownLatch来控制所有算法线程的同步
3、全部计算完成后再求平均数 */public class CountDownLatchTask {    public static void main(String[] args) {CountDownLatchTask countDownLatchTask = new CountDownLatchTask();countDownLatchTask.startThreads(5);}    //根据线程数和选择的算法 调度算法对应的实现private void startThreads(int threadNumber) {CountDownLatch countDownLatch = new CountDownLatch(threadNumber);        for (int i = 0; i < threadNumber; i++) {            new Thread(new Runnable() {@Override                public void run() {System.out.println("线程算法实现:" + Thread.currentThread().getName());countDownLatch.countDown();}}).start();}        try {countDownLatch.await();System.out.println("加权求平均数");} catch (InterruptedException e) {e.printStackTrace();}}
}

  在分析原理实现前,总结下CountDownLatch的作用就是阻塞其他线程直到条件允许后才释放该阻塞,除了上述这个小案例,实际工作中还有很多可以使用CountDownLatch的场景,比如解析Excel文件时可以同时解析多个Sheet页,所有的Sheet解析完成才算完成了Excel文件的解析。从这个代码中也可以看到CountDownLatch的主要方法就是await和countDown,下面将以这两个方法来分析下CountDownLatch的原理实现。

2、 源码原理解析

 2.1 await方法

  调用await方法会阻塞当前线程直到计数器的数值为0,方法如下:

public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1); //共享式获取AQS的同步状态}

  调用的是AQS的acquireSharedInterruptibly方法:

public final void acquireSharedInterruptibly(int arg)            throws InterruptedException {        if (Thread.interrupted())//线程中断 说明闭锁对线程中断敏感throw new InterruptedException();        if (tryAcquireShared(arg) < 0) //闭锁未使用完成 线程进入同步队列自旋等待             doAcquireSharedInterruptibly(arg);}

  其中tryAcquireShared依赖的是Sync的实现,和之前的ReentrantLock、ReentrantReadWriteLock及Semaphore相比,CountDownLatch的Sync只提供了一种方式,代码如下:

protected int tryAcquireShared(int acquires) {            return (getState() == 0) ? 1 : -1; //AQS的同步状态为0则闭锁结束 可以进行下一步操作}

  doAcquireSharedInterruptibly方法就不再赘述,和之前Semaphore的实现是一致的,本质上仍然是AQS同步队列的入队自旋等待。

2.2 countDown方法

  调用countDown方法会将计数器的数值减1直到计数器为0,方法如下:

public void countDown() {sync.releaseShared(1);}

  和Semaphore一样,调用的是AQS的releaseShared方法:

public final boolean releaseShared(int arg) {        if (tryReleaseShared(arg)) {//减少闭锁的计数器doReleaseShared();//唤醒后续线程节点return true;}        return false;}

  其中tryReleaseShared依赖的是Sync的实现,和之前的ReentrantLock、ReentrantReadWriteLock及Semaphore相比,CountDownLatch的Sync只提供了一种方式,代码如下:

protected boolean tryReleaseShared(int releases) {            // Decrement count; signal when transition to zerofor (;;) {                int c = getState();                if (c == 0)                    return false; //计数器已经是0了int nextc = c-1; //计数器减1if (compareAndSetState(c, nextc)) //CAS更新同步状态return nextc == 0;加群:874811168 一起学习,一起进步进群即可免费领取资料一份}}

  唤醒后续线程节点的doReleaseShared也不再赘述,和之前Semaphore的实现是一致的。

  总结:CountDownLatch类使用AQS同步状态来表示计数。在await时,所有的线程进入同步队列自旋等待,在countDown时,获取闭锁成功的线程会减少闭锁的计数器,同时唤醒后续线程取获取闭锁,直到await中的计数器为0,获取到闭锁的线程才可以通过,执行下一步操作。

出处:https://www.cnblogs.com/iou123lg/p/9739697.html

转载于:https://my.oschina.net/u/3971241/blog/2222704

Java并发编程-CountDownLatch相关推荐

  1. Java 并发编程CountDownLatch的应用与源码解析

    应用场景 CountDownLatch是一个多线程控制工具.用来控制线程的等待. 设置需要countDown的数量,然后每一个线程执行完毕后调用countDown()方法,而在主线程中调用await( ...

  2. Java并发编程--CountDownLatch

    概述 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行. CountDownLatch使用一个计数器count实现,构建CountDownL ...

  3. java 并发统计_java并发编程|CountDownLatch计数器

    0x01,CountDownLatch介绍 CountDownLatch是一个计数器,作为java并发编程中三个组件之一,这个组件的使用频率还是很多的.这里分享下自己画的java并发编程组件的图,后面 ...

  4. 【Java 并发编程】CountDownLatch 简介

    文章目录 I CountDownLatch 概念 II CountDownLatch 使用流程 III CountDownLatch API 简介 I CountDownLatch 概念 1. 概念 ...

  5. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    2019独角兽企业重金招聘Python工程师标准>>> Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一 ...

  6. Java 并发编程系列之闭锁(CountDownLatch)

    在讲闭锁之前,我们先来思考一个问题:在多线程环境下,主线程打印一句话,如何保证这句话最后(其他线程全部执行完毕)打印? 博主目前可以想到的实现方式有两种.一种是通过 join() 方法实现,另一种就是 ...

  7. Java并发编程工具类:CountDownLatch、CyclicBarrier、Semaphore

    在jdk5中,java提供了一些非常有用的辅助工具类,包括CountDownLatch和CyclicBarrier(两者都可以实现线程之间的通信).Semaphore(控制方法被线程访问的数量),他们 ...

  8. 【Java并发编程实战】 5.5.1章节 闭锁 CountDownLatch 实现

    文章目录 1. 什么是闭锁 2. 闭锁的应用场景 3. 闭锁的实现 4. CountDownLatch原理 5. 使用案例 5.1 入门案例 5.2 复杂案例 1. 什么是闭锁 闭锁(latch)是一 ...

  9. Java并发编程笔记之 CountDownLatch闭锁的源码分析

    转 自: Java并发编程笔记之 CountDownLatch闭锁的源码分析 ​ JUC 中倒数计数器 CountDownLatch 的使用与原理分析,当需要等待多个线程执行完毕后在做一件事情时候 C ...

最新文章

  1. [RN] React Native 自定义 底部 弹出 选择框 实现
  2. Docker swarm 集群搭建
  3. java 支付重复问题_Airbnb支付系统如何在分布式环境下避免重复打款
  4. python sanic orm_基于sanic的微服务框架 - 架构分析
  5. 【转】JAVA中的浅拷贝和深拷贝
  6. Cadence工具系列介绍
  7. Hexo博文置顶(自定义排序)
  8. Vue 上传图片裁剪
  9. 平衡二叉树 构造方法RR RL LL LR
  10. 根据接口获取得数据,布局两列多行的代码写法
  11. aar打包依赖 android_打包依赖.aar文件以及坑总结
  12. 理解HTTP Referer
  13. Python爬取租房数据实例,据说可以入门爬虫的小案例!
  14. Nginx是干什么的
  15. HDU2795 Billboard 线段树
  16. oracle中授予插入的权限,向 Oracle 中的 Reviewer 工作空间组件授予权限
  17. c语言中有裁剪字符串的函数吗,C语言中的字符串截取函数
  18. Github Emojis API
  19. c3520 宝骏凯立德地图_凯立德2018车载导航地图-2018年05月凯立德高清优化版C2939-C7M05-3H21J22最新版 - 极光站...
  20. R中数据的标准化0-1标准化

热门文章

  1. 高仿书旗小说 Flutter版,支持iOS、Android
  2. 看我是如何利用升级系统一键GetShell
  3. cd、mkdir、rmdir、touch、rm命令,绝对路径与相对路径
  4. 销售易发布旗舰版移动CRM及PaaS平台 产品比肩Salesforce
  5. JavaScript对象克隆
  6. iOS开发-策略模式
  7. Linux 网络编程(TCP)
  8. mysql5.6安装
  9. cookie 和 session 机制
  10. 软件不可靠,服务是王道