CountDownLatch的实现原理

CountDownLatch是java并发包中辅助并发的工具类,目的是让并发运行的代码在某一个执行点阻塞,直到所有条件都满足,这里的条件就是调用countDown()方法,有点类似计数器的功能。

用法如

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        //如果没有countDown()操作,直接调用await方法则永远不会打印最后一行
        countDownLatch.countDown();
        countDownLatch.countDown();
        countDownLatch.await();
        System.out.println("运行结束");
    }

构造函数中传入的数字2,表示需要2次countDown()方法调用,否则代码会一直阻塞在await()方法调用处  

比较常见的用法如,主线程声明一个CountDownLatch,然后多线程countDown,主线程在等待

 1     public static void testMultiThread() throws InterruptedException {
 2         int threadNum = 2;
 3         final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
 4         ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
 5         for(int i=0;i<threadNum;i++){
 6             executorService.execute(new Runnable() {
 7                 public void run() {
 8                     System.out.println("我的任务,打印出一句话");
 9                     countDownLatch.countDown();
10                 }
11             });
12         }
13         countDownLatch.await();
14         System.out.println("全部任务都结束了,欧耶");
15         executorService.shutdown();
16     }

运行结果

我的任务,打印出一句话
我的任务,打印出一句话
全部任务都结束了,欧耶

Process finished with exit code 0

如果把第三行代码修改成

3         final CountDownLatch countDownLatch = new CountDownLatch(threadNum+1);

那么程序将永远无法打印出

全部任务都结束了,欧耶

以上是这个类的表象行为,那么它是如何在多线程做到这样的功能呢

先来看看它的类结构

CountDownLacth中,有6个public的方法,一个内部私有类Sync,及一个Sync实例的变量sync

Sync是这个类的关键,它保证了countDown(),await()方法在多线程场景下可以保证countDownLatch的可见性(正常的同步)

我们先来自己实现一个CountDownLacth类,使用synchronized关键字实现

MyCountDownLatch模拟了countDown和await方法,通过synchronized和私有变量state来达到这个目的。synchronized的劣势在于锁机制完全互斥,并发量高时性能下降比较明显,无法维持常态化的性能(JDK 5)。因此CountDownLatch以及并发包中的类都采用了取巧的方式,通过线程自旋来追求线程响应时间,而不是让线程只能一直等待锁被释放再竞争。1.6之后,synchronized的性能和ReentrantLock的性能其实已经相当,偏向锁也改进了一个线程重复获取锁时不需要cpu切换上下文。

时间: 10-20

CountDownLatch的实现原理的相关文章

Java 并发工具CountDownLatch和CyclicBarrier 原理解析

[TOC] Java 并发工具CountDownLatch和CyclicBarrier 原理解析 一,简介 CountDownLatch 允许一个或者多个线程等待其他线程完成操作. CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程达到一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行. 二,代码演示 CountDownLatchDemo public class Co

Java并发包中CountDownLatch的工作原理、使用示例

1. CountDownLatch的介绍 CountDownLatch是一个同步工具,它主要用线程执行之间的协作.CountDownLatch 的作用和 Thread.join() 方法类似,让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒.在直接创建线程的年代(Java 5.0 之前),我们可以使用 Thread.join().在线程池出现后,因为线程池中的线程不能直接被引用,所以就必须使用 CountDownLatch 了. CountDownLatch主要有两个方法,当一个或多个线程调

Java系列笔记(6) - 并发(上)

目录 1,基本概念 2,volatile 3,atom 4,ThreadLocal 5,CountDownLatch和CyclicBarrier 6,信号量 7,Condition 8,Exchanger 在Java中,JVM.并发.容器.IO/NIO是我认为最重要的知识点,本章将介绍其中的并发,这也是从“会Java”到精通Java所必须经历的一步.本章承接上一张<Java系列笔记(5) - 线程>,其中介绍了Java线程的相关知识,是本章介绍内容的基础,如果对于线程不熟悉的,可以先阅读以下这

Java面试题集(一)问题清单

java基础篇: 1.1.Java基础 (1)面向对象的特性:继承.封装和多态 (2)final.finally.finalize 的区别 (3)Exception.Error.运行时异常与一般异常有何异同 (4)请写出5种常用的runtime exception (5)int 和 Integer 有什么区别.Integer的值缓存范围 (6)包装类.装箱.拆箱 (7)String.StringBuilder.StringBuffer (8)重载和重写的区别 (9)抽象类和接口的区别 (10)说

java并发学习03---CountDownLatch 和 CyclicBarrier

CountDownLatch,顾名思义就是一个倒计时器.(其实Latch的意思是门闩,这个词的本意是不断的计数减一,减到0了就打开门闩放行,但通常我们还是叫它倒计时器) 这个倒计时器和我们传统意义上的倒计时器并不完全一样,这个倒计时器的意思是,一开始规定几个线程(比如说我们这里一开始有10个线程),那么每个线程结束之后,会调用倒计时器实例对象的方法,让它的"计数器"减一,当计数器减到0时,门闩打开放行. CountDownLatch的简单原理和应用 : 在主线程调用CountDownL

Java多线程之---用 CountDownLatch 说明 AQS 的实现原理

本文基于 jdk 1.8 . CountDownLatch 的使用 前面的文章中说到了 volatile 以及用 volatile 来实现自旋锁,例如 java.util.concurrent.atomic 包下的工具类.但是 volatile 的使用场景毕竟有限,很多的情况下并不是适用,这个时候就需要 synchronized 或者各种锁实现了.今天就来说一下几种锁的实现原理. 先来看一个最简单的 CountDownLatch 使用方法,例子很简单,可以运行看一下效果.CountDownLat

CountDownLatch实现原理

CountDownLatch的原理 这个类一般的应用场景为:一个线程等待另外N(N>=1)个线程的事情搞完了,自己再搞事情.具体应用代码大致如下: public class CountDownLatchTest { private static final int THREAD_COUNT = 10; private CountDownLatch latch = new CountDownLatch(THREAD_COUNT); public void test() throws Excepti

CountDownLatch和Cyclicbarrier概念、区别及原理

CountDownLatch和Cyclicbarrier概念.区别及原理 1.概念   CountDownLatch:具有计数器的功能,等待其他线程执行完毕,主线程在继续执行,用于监听某些初始化操作,并且线程进行阻塞,等初始化执行完毕后,通知主线程继续工作执行.值得注意的是CountDownLatch计数的次数一定要与构造器传入的数字一致,比如构造器传入的是3,则countDown()一定要执行3次,否则线程将一直阻塞.CountDownLatch通常用来控制线程等待,它可以让线程等待倒计时结束

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

1.CountDownLatch介绍 1.1 CountDownLatch的使用,请参考文章 多线程(七.同步计数器-CountDownLatch 2.案例分析 2.1 说明: 1.Thread-1执行await,等待主线程放行;2.Thread-2执行await,等待主线程放行:3.主线程执行countDown()放行. 3.源码分析 3.1 CountDownLatch的构造函数和如何使用AQS的同步状态: 1.CountDownLatch的初始计数器就是直接设置AQS的同步状态值state