`
BrokenDreams
  • 浏览: 254679 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
68ec41aa-0ce6-3f83-961b-5aa541d59e48
Java并发包源码解析
浏览量:100427
社区版块
存档分类
最新评论

Jdk1.6 JUC源码解析(9)-CountDownLatch

阅读更多

Jdk1.6 JUC源码解析(9)-CountDownLatch

作者:大飞

 

功能简介:
  • CountDownLatch是一种锁,称为闭锁。可以让一个或多个线程等待另外一个或多个线程执行完毕后再执行。
  • CountDownLatch也是基于AQS构建,使用共享模式。
  • CountDownLatch中提供一个count值来表示要等待的(其他任务)完成次数,常规用法有两种:Count(1)和Count(N)。举个栗子,百米赛跑,N个选手,每个选手可以看成是一个线程。起跑前,选手准备(线程启动,然后在Count(1)上阻塞),当发令枪响后(相当于Count(1)闭锁释放),选手一起起跑(相当于线程通过Count(1)继续执行),当所有选手都通过终点(相当于Count(N)闭锁释放),然后再统计成绩。
源码分析:
  • CountDownLatch基于AQS构建,首先看下内部的同步器:
    /**
     * CountDownLatch内部同步器,利用AQS的state来表示count。
     */
    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;
        Sync(int count) {
            setState(count);
        }
        int getCount() {
            return getState();
        }

        protected int tryAcquireShared(int acquires) {
            //如果当前count为0,那么方法返回1,
            //按照之前对AQS的分析,请求成功,并唤醒同步队列里下一个共享模式的线程(这里都是共享模式的)。
            //如果当前count不为0,那么方法返回-1,请求失败,当前线程最终会被阻塞(之前会不止一次调用tryAcquireShared)。
            return getState() == 0? 1 : -1;
        }
        protected boolean tryReleaseShared(int releases) {
            // 如果count为0,返回false,相当于释放失败,因为此时闭锁处于开放状态,没有必要在打开。
            // 如果count不为0,递减count。
            // 最后如果count为0,说明关闭的闭锁打开了,那么返回true,后面会唤醒等待队列中的线程。
            // 如果count不为0,说明闭锁还是处于关闭状态,返回false。
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }

 

  • 内部的实现也很简单了: 
public class CountDownLatch {
    private final Sync sync;
    
    ...
    /**
     * 根据给定的count创建一个CountDownLatch。
     */
    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }
    /**
     * 如果当前count为0,那么方法立即返回。
     *
     * 如果当前count不为0,那么当前线程会一直等待,直到count被(其他线程)减到0或者当前线程被中断。
     */
    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    /**
     * 如果当前count为0,那么方法立即返回true。
     *
     * 如果当前count不为0,那么当前线程会一直等待,直到count被(其他线程)减到0或者当前线程被中断或者超时。
     * 成功返回true,超时返回false,被中断抛异常。
     */
    public boolean await(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }
    /**
     * 如果当前count大于0,递减count。如果递减后,count等于0,那么AQS中所有等待线程都被唤醒。
     *
     * 如果当前count等于0,什么事都不会发生。
     */
    public void countDown() {
        sync.releaseShared(1);
    }
    /**
     * 获取当前count值。
     */
    public long getCount() {
        return sync.getCount();
    }
    /**
     * Returns a string identifying this latch, as well as its state.
     * The state, in brackets, includes the String {@code "Count ="}
     * followed by the current count.
     *
     * @return a string identifying this latch, as well as its state
     */
    public String toString() {
        return super.toString() + "[Count = " + sync.getCount() + "]";
    }
}

 

       小总结一下:

              1.建立一个count为n的闭锁后,闭锁的内部计数为n,这时如果有线程调用闭锁的await方法,会阻塞。
              2.每一次调用闭锁的countDown方法,内部计数就会减1,当闭锁的countDown方法被调用n次后,内部计数减为0,这时在闭锁await方法上等待的线程就被唤醒了。
 

       CountDownLatch的代码解析完毕!

 

 

       参见:Jdk1.6 JUC源码解析(6)-locks-AbstractQueuedSynchronizer

 

 

分享到:
评论

相关推荐

    JavaCommon:Java基础用法,集合,线程,JUC,jdk5--8各个版本特性。

    该项目还深入解析了从JDK 5到JDK 8各版本的重要特性,为开发者提供了丰富的代码示例和源码分析。 1. **Java基础用法**: - **变量与数据类型**:Java支持基本数据类型如int、float、char等,以及引用类型如类、...

    JDK1.8:JDK1.8源码解析-源码解析

    在深入探讨JDK1.8源码解析之前,先理解一下JDK的含义:Java Development Kit,即Java开发工具包,是Java编程语言的核心组成部分,提供了编写、编译和运行Java应用程序所需的所有工具。JDK1.8是Oracle公司发布的Java ...

    A-JUC-JVM-Java并发知识..pdf

    JUC的同步器包括CountDownLatch、CyclicBarrier、Semaphore等,它们是为了解决多个线程协作完成特定任务的工具。例如,CountDownLatch可以让一些线程等待其他线程完成操作后再继续执行,而CyclicBarrier则让一组线程...

    thread_analysis:JDK中JUC学习记录

    本篇将深入解析JDK中的JUC包,探讨其核心组件和机制,帮助开发者更好地理解和利用这些高级并发工具。 一、线程池ExecutorService ExecutorService是JUC包中的核心接口,它扩展了Executor接口,提供了管理和控制线程...

    javajdk8源码-concurrencyJava:基于JDK8源码学习并发编程知识

    总之,这份"javajdk8源码-concurrencyJava"的学习资料会带你深入理解JDK 8中并发编程的各种机制和工具,通过源码解析,你可以更好地掌握Java并发编程的精髓,从而编写出高效、安全的多线程应用。对于系统开源领域的...

    艾编程coding老师:JUC 并发编程 + 底层原理.pdf

    JUC(java.util.concurrent)是Java提供的一个并发编程工具包...要掌握JUC并发编程及其底层原理,除了通过阅读官方文档和源码学习外,还需要大量实践和经验积累,才能够真正理解和应用JUC中的并发工具来解决实际问题。

    Java并发包源码分析(JDK1.8)

    Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...

    JAVA面试题大全

    - CountDownLatch、CyclicBarrier、Semaphore的用途。 - Atomic类的理解和使用,如AtomicInteger、AtomicReference。 13. **Spring框架** - Spring的核心模块和依赖注入(DI)的概念。 - AOP(面向切面编程)的...

    最新JAVA经典面试题(有答案)

    - 动态代理的理解,包括JDK动态代理和CGLIB动态代理。 7. **设计模式**: - 了解常见的设计模式,如单例、工厂、观察者、装饰者、适配器、代理等,并能结合实际场景应用。 8. **JVM**: - 垃圾回收机制(GC)的...

    Java面试宝典2018-最全面试资料

    - **JUC并发工具类**:CountDownLatch、CyclicBarrier、Semaphore、ThreadPoolExecutor的使用。 - **Maven或Gradle**:构建工具的使用,配置管理,依赖管理。 - **单元测试**:JUnit、Mockito等工具的使用。 ...

    尚硅谷大厂面试题第二季周阳主讲整理笔记

    - **java.util.concurrent** 包含并发工具类,如ExecutorService、Semaphore、CountDownLatch等。 - **java.util.concurrent.atomic** 提供了原子变量类,如AtomicInteger,用于无锁编程,保证单个变量的原子操作。 ...

    JVM_JUC_Demo:练习案例

    在Java世界中,JVM(Java Virtual Machine)和JUC(Java Concurrency Utilities)是两个极其重要的概念。JVM是Java程序的运行平台,而JUC则是Java并发编程的重要工具集。这个名为“JVM_JUC_Demo”的实践案例旨在帮助...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第二阶段46讲、ClassLoader链接阶段(验证,准备,解析)过程详细介绍.mp4 │ 高并发编程第二阶段47讲、ClassLoader初始化阶段详细介绍clinit.mp4 │ 高并发编程第二阶段48讲、JVM内置三大类加载器...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段46讲、ClassLoader链接阶段(验证,准备,解析)过程详细介绍.mp4 │ 高并发编程第二阶段47讲、ClassLoader初始化阶段详细介绍clinit.mp4 │ 高并发编程第二阶段48讲、JVM内置三大类加载器...

    jdkLearning:阅读java原始代码包含:集合,JUC,Executor体系

    这个"jdkLearning"项目专注于深入理解JDK的源代码,特别是集合、并发编程(JUC)和Executor服务这三个核心领域。通过阅读和分析这些源码,开发者可以更深入地了解Java平台的工作原理,提升编程技能,并优化应用程序...

    java 并发编程

    JDK中的并发框架JUC(java.util.concurrent)包括了线程池、并发容器、原子操作和并发工具类。JUC的设计目标是提供生产级别的线程安全的容器和类,减少同步问题的复杂性,并且尽量避免重复发明轮子。线程池是管理...

    Java基础笔记(包括底层原理)

    JUC(Java Concurrency Utilities)提供了高级同步工具,如Semaphore、CyclicBarrier和CountDownLatch,以及并发容器如ConcurrentHashMap,提升了多线程编程的便利性和性能。 总的来说,Java基础知识覆盖了从简单的...

    Chinese_AQS:添加中文注释, 重新按业务部门开发工程师的思维角度组织代码中的方法顺序, 使中国程序员轻松理解 AbstractQueuedSynchronizer;

    《Chinese_AQS:为中国程序员解析AbstractQueuedSynchronizer》 在Java并发编程领域,AbstractQueuedSynchronizer(AQS)是一个至关重要的组件,它为实现锁和其他同步构建块提供了基础。然而,由于其复杂性和原始...

    资深程序员的Java面试题总结汇总.pdf

    13. JUC中的并发工具包括Semaphore(信号量)、CyclicBarrier(回环栅栏)、CountDownLatch(计数器门闩)等。 14. ReadWriteLock提供了读写锁分离,提高并发性能;StampedLock提供了更细粒度的锁控制。 15. 通过...

Global site tag (gtag.js) - Google Analytics