文档章节

CountDownLatch详解

xpbob
 xpbob
发布于 01/27 15:43
字数 1033
阅读 46
收藏 0

功能描述

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
常见用法
多个人等一个信号后继续执行操作。例如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 zero
            for (;;) {
                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个人,车都开了一半了,不会考虑再回去。随意修改约束值会带来很多逻辑上的问题。
  2. CountDownLatch无限等待 countDown没有被调用,那么await就会一直等下去。countDown常见没有被调用的情况:异常中断,线程池拒绝策略。 可以使用
public boolean await(long timeout, TimeUnit unit)

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

© 著作权归作者所有

上一篇: 字符常量
xpbob

xpbob

粉丝 98
博文 98
码字总数 80029
作品 0
高级程序员
私信 提问
CountDownLatch源码解析

CountDownLatch 相比ReentranceLock,CountDownLatch的流程还是相对比较简单的,CountDownLatch也是基于AQS,它是AQS的共享功能的一个实现。 下面从源代码的实现上详解CountDownLatch。 1、C...

maxam0128
2018/01/23
0
0
并发编程系列:4大并发工具类的功能、原理、以及应用场景

一:并发工具包 1.并发工具类 提供了比synchronized更加高级的各种同步结构:包括CountDownLatch、CyclicBarrier、Semaphore等,可以实现更加丰富的多线程操作。 2.并发容器 提供各种线程安全...

游人未归
2018/11/19
0
0
Java集合之Vector详解

简介 Vector的内部实现类似于ArrayList,Vector也是基于一个容量能够动态增长的数组来实现的,该类是JDK1.0版本添加的类,它的很多实现方法都加入了同步语句,因此是线程安全的(但Vector其实...

欧阳海阳
2018/06/12
0
0
【Java并发专题】27篇文章详细总结Java并发基础知识

努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! github:https://github.com/CL0610/Java-concurrency,欢迎题issue和Pull request。所有的文档都是自己亲自码的,如果觉...

你听___
2018/05/06
0
0
java.util.concurrent包(5)——CountDownLatch使用

Java的concurrent包里面的CountDownLatch其实可以被看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是同时只能有一个线程去减这个计数器里面的...

woshixuye111
2014/06/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Protocol Buffers 简介

文档编辑和持续集成状态: 本文档的 Protocol Buffer 的中文文档使用的是 Asciidoctor 进行编排的 http://docs.ossez.com/protocol-buffers-docs/index.html(本 WIKI 中的内容将会与在线发布...

honeymoose
今天
3
0
uniapp + bootstrapvue 移动/PC 一套搞定 (一)配置bootstrapvue

1.准备文件 自己到DCloud官网: http://dcloud.io/ 去下载官方的IDE Hbuilder,新建一个空的uniapp项目即可。 uniapp框架自带优化的vue,我们仅仅需要准备以下三个文件: bootstrap.min.css ...

panyunxing
今天
11
0
Android Camera原理之camera service类与接口关系

camera service主要是指 frameworks/av/services/camera/下面的代码,最近在看这一块的代码,为了更好地理清这一块的代码,也为了后续学习camera方便一些,我觉得很有必要理一下这一块的整体...

天王盖地虎626
今天
6
0
Golang学习笔记

[TOC] Golang学习笔记 这个学习笔记是最早在1.初,版本左右的时候写的,和当前最新的版本可能会有较大的差异. 因为成文比较早,文章里面又有很多自己的见解,有些东西当时理解的不太透彻可能写错...

我爱吃炒鸡
今天
18
0
科技赋能成效显著!金融壹账通两大赋能项目荣获IDC大奖

7月19日,2019IDC中国未来金融论坛曁颁奖典礼于北京举办。由金融壹账通赋能的长春农商银行多人视频面审智能风控系统、包头农商银行互联网银行SaaS服务两大项目因在项目的创新性、技术领先性、...

IFTNews
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部