功能描述

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
常见用法
多个人等一个信号后继续执行操作。例如5个运动员,等一个发令员的枪响。
一个人等多个人的信号。旅游团等所有人签到完成才开始出发。
我们最常见见到使用的地方是zk获取连接的时候

       final CountDownLatch countDownLatch=new CountDownLatch(1); ZooKeeper zooKeeper=new ZooKeeper(zk_url, time_out, new Watcher() { public void process(WatchedEvent watchedEvent) { Event.KeeperState state = watchedEvent.getState(); Event.EventType type = watchedEvent.getType(); if(Event.KeeperState.SyncConnected==state){ if(Event.EventType.None==type){ //调用此方法测计数减一 countDownLatch.countDown(); } } } }); //阻碍当前线程进行,除非计数归零 countDownLatch.await();

这里了也可以看到很明确的使用方法,countDown直到0,await的线程才会继续执行。

原理

CountDownLatch内部使用了共享锁。如果这里还不知道共享和独占的区别,可以看前面的aqs速读。
获取锁成功的方法很简单

        protected int tryAcquireShared(int acquires) {return (getState() == 0) ? 1 : -1;}

共享锁有个约定,返回有三种情况。

  • 0为获取锁且没有其他资源
  • 正数 获取锁并且还有其他资源
  • 负数 获取锁资源失败

共享锁在tryAcquireShared返回大于0的值的时候,会唤醒其他停顿状态加锁线程。由于没有对state的增加操作,所以当state变成0的时候,所有尝试加锁的线程都会被唤醒。

        protected boolean tryReleaseShared(int releases) {// Decrement count; signal when transition to zerofor (;;) {int c = getState();if (c == 0)return false;int nextc = c-1;if (compareAndSetState(c, nextc))return nextc == 0;}}

释放锁的操作,就是把state的值减一,当只有state变成0的时候,才返回true,tryReleaseShared返回true的时候会触发唤醒其他加锁线程的操作。
通过上面的过程,我们可以看到CountDownLatch中的共享锁的加锁和释放锁的过程,下面看看是如何和CountDownLatch结合的。

    public CountDownLatch(int count) {if (count < 0) throw new IllegalArgumentException("count < 0");this.sync = new Sync(count);}

CountDownLatch的构造里会初始化共享锁,并且设置state的值。

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

countDown是释放锁,最终会调用到tryReleaseShared。

    public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);}

await是加锁,最终会调用到 tryAcquireShared。
CountDownLatch就是一个不断释放锁的过程。

常见问题

  1. CountDownLatch是不能够重用的
    根据上面的解析,大家也发现,共享锁加锁的操作并不会增加state的值。CountDownLatch中state一旦变成0就没有提供其他方式增长回去了。

所以CountDownLatch是一次性消耗品,用完就得换新的。这样设计也是比较正常的,对状态的要求比较严格,例如都开车了你再告诉司机,这次加了5个人,车都开了一半了,不会考虑再回去。随意修改约束值会带来很多逻辑上的问题。

  1. CountDownLatch无限等待
    countDown没有被调用,那么await就会一直等下去。countDown常见没有被调用的情况:异常中断,线程池拒绝策略。

可以使用

public boolean await(long timeout, TimeUnit unit)

根据业务情况,增加一个最大等待时间。使用这种方式,需要对失败的各种情况作出业务上的对应处理,否则就出现各种数据不正确的问题。也可以对countDown的线程做好异常处理,最好使用另外一个线程池来处理这些线程。这种情况就需要对业务不能停顿时间特别长,导致线程池的资源被耗光的情况做处理。如果是想通过new Thread避免,就需要考虑线程突然暴涨的问题。

CountDownLatch详解相关推荐

  1. CountDownLatch详解以及用法示例

    一.什么是countDownlatch CountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量.每当一个线程完成了自己的任务,计数器的值就相应得减1.当计数器到达0 ...

  2. CountDownLatch详解 1

    参考:Java并发编程的艺术 JDK版本:AdoptOpenJDK 11.0.2+9 1 概念 CountDownLatch允许一个或者多个线程去等待其他线程完成操作. CountDownLatch接 ...

  3. Java并发编程之CountDownLatch/CyclicBarrierDemo/SemaphoreDemo详解

    CountDownLatch详解 什么是CountDownLatch? 代码说明一 :班长锁门 代码说明二:秦国统一六国 什么是CyclicBarrierDemo? 代码说明一:集齐7个龙珠,召唤神龙 ...

  4. 40000+字超强总结?阿里P8把Java全栈知识体系详解整理成这份PDF

    40000 +字长文总结,已将此文整理成PDF文档了,需要的见文后下载获取方式. 全栈知识体系总览 Java入门与进阶面向对象与Java基础 Java 基础 - 面向对象 Java 基础 - 知识点 ...

  5. Java多线程系列(九):CountDownLatch、Semaphore等4大并发工具类详解

    之前谈过高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 ,以及高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8) 今天主要介绍concurre ...

  6. 最接地气的详解CountDownLatch闭锁应用与实现机制

    Hello,大家好,我是Steafan,今天为大家带来最接地气的详解CountDownLatch闭锁应用与实现机制.之前在编写多线程高并发业务场景时,因为那时刚刚接触高并发程序的编写,所以从网上了解了 ...

  7. CountDownLatch用法详解

    CountDownLatch用法详解 CountDownLatch使用场景 线程计数器 用于线程执行任务,计数 等待线程结束 用法一: 等待所有的事情都做完 //程序计数器CountDownLatch ...

  8. 高并发编程_高并发编程系列:7大并发容器详解(附面试题和企业编程指南)...

    不知道从什么时候起,在Java编程中,经常听到Java集合类,同步容器.并发容器,高并发编程成为当下程序员需要去了解掌握的技术之一,那么他们有哪些具体分类,以及各自之间的区别和优劣呢? 只有把这些梳理 ...

  9. 并发编程-04线程安全性之原子性Atomic包的4种类型详解

    文章目录 线程安全性文章索引 脑图 概述 原子更新基本类型 Demo AtomicBoolean 场景举例 原子更新数组 Demo 原子更新引用类型 Demo 原子更新字段类型 使用注意事项: Dem ...

  10. java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题

    先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...

最新文章

  1. 《软件需求模式》阅读笔记04
  2. NYOJ 679 The Weight of Tree 搜索+dp+邻接表
  3. 关于JTAG——韦东山嵌入式Linux视频学习笔记02
  4. C/C++ VS中调用matlab函数的方法
  5. 1668智能下数教程视频_你需要的教程合集更新
  6. oracle11g 导出表报EXP-00011:table不存在。
  7. matlab 格式化文件,Matlab 文件格式化/Matlab Source File Formator
  8. nodejs代理请求转发
  9. python基础练习题:重新排序【难度:1级】--景越Python编程实例训练营,不同难度Python习题,适合自学Python的新手进阶
  10. win10好用的小软件(小插件)
  11. Python3图片中竖排文字
  12. 笔记 GWAS 操作流程2-5:杂合率检验
  13. 米家接入HomeKit系列四:HomeBridge搭建、配置与接入米家设备
  14. 技术水平真的很重要!技术详细介绍
  15. 为什么大数据平台要回归SQL
  16. RAM、SRAM、DRAM、SDRAM、DDRSDRAM等之间的区别
  17. 雅虎股东紧盯阿里巴巴IPO蛋糕
  18. 大商创是用哪种php柜架写的,手把手教你做一套大商创店铺模板(1.9版)
  19. springcloud使用RestTemplate进行接口调用
  20. icode 三级训练场if入门1-10关

热门文章

  1. PWN--collision
  2. 【OpenCV】基于图像处理和模式识别的火灾检测方法
  3. 通过路径传值id进行页面判断
  4. VirtualPC2007添加Shared Folder的方法for dos
  5. HTML image button
  6. 如何调整一个 IFrame 到其内容的大小不显示滚动条[微软帮助]
  7. 苹果 macOS Big Sur 11.2.3 正式版发布
  8. VegasMovie Studio无法安装怎么办?
  9. CTU 2019 Open Contest I.SixPack (WA39)
  10. document.body.scrollTop滚动失效