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
相关推荐
该项目还深入解析了从JDK 5到JDK 8各版本的重要特性,为开发者提供了丰富的代码示例和源码分析。 1. **Java基础用法**: - **变量与数据类型**:Java支持基本数据类型如int、float、char等,以及引用类型如类、...
在深入探讨JDK1.8源码解析之前,先理解一下JDK的含义:Java Development Kit,即Java开发工具包,是Java编程语言的核心组成部分,提供了编写、编译和运行Java应用程序所需的所有工具。JDK1.8是Oracle公司发布的Java ...
JUC的同步器包括CountDownLatch、CyclicBarrier、Semaphore等,它们是为了解决多个线程协作完成特定任务的工具。例如,CountDownLatch可以让一些线程等待其他线程完成操作后再继续执行,而CyclicBarrier则让一组线程...
本篇将深入解析JDK中的JUC包,探讨其核心组件和机制,帮助开发者更好地理解和利用这些高级并发工具。 一、线程池ExecutorService ExecutorService是JUC包中的核心接口,它扩展了Executor接口,提供了管理和控制线程...
总之,这份"javajdk8源码-concurrencyJava"的学习资料会带你深入理解JDK 8中并发编程的各种机制和工具,通过源码解析,你可以更好地掌握Java并发编程的精髓,从而编写出高效、安全的多线程应用。对于系统开源领域的...
JUC(java.util.concurrent)是Java提供的一个并发编程工具包...要掌握JUC并发编程及其底层原理,除了通过阅读官方文档和源码学习外,还需要大量实践和经验积累,才能够真正理解和应用JUC中的并发工具来解决实际问题。
Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...
- CountDownLatch、CyclicBarrier、Semaphore的用途。 - Atomic类的理解和使用,如AtomicInteger、AtomicReference。 13. **Spring框架** - Spring的核心模块和依赖注入(DI)的概念。 - AOP(面向切面编程)的...
- 动态代理的理解,包括JDK动态代理和CGLIB动态代理。 7. **设计模式**: - 了解常见的设计模式,如单例、工厂、观察者、装饰者、适配器、代理等,并能结合实际场景应用。 8. **JVM**: - 垃圾回收机制(GC)的...
- **JUC并发工具类**:CountDownLatch、CyclicBarrier、Semaphore、ThreadPoolExecutor的使用。 - **Maven或Gradle**:构建工具的使用,配置管理,依赖管理。 - **单元测试**:JUnit、Mockito等工具的使用。 ...
- **java.util.concurrent** 包含并发工具类,如ExecutorService、Semaphore、CountDownLatch等。 - **java.util.concurrent.atomic** 提供了原子变量类,如AtomicInteger,用于无锁编程,保证单个变量的原子操作。 ...
在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内置三大类加载器...
│ 高并发编程第二阶段46讲、ClassLoader链接阶段(验证,准备,解析)过程详细介绍.mp4 │ 高并发编程第二阶段47讲、ClassLoader初始化阶段详细介绍clinit.mp4 │ 高并发编程第二阶段48讲、JVM内置三大类加载器...
这个"jdkLearning"项目专注于深入理解JDK的源代码,特别是集合、并发编程(JUC)和Executor服务这三个核心领域。通过阅读和分析这些源码,开发者可以更深入地了解Java平台的工作原理,提升编程技能,并优化应用程序...
JDK中的并发框架JUC(java.util.concurrent)包括了线程池、并发容器、原子操作和并发工具类。JUC的设计目标是提供生产级别的线程安全的容器和类,减少同步问题的复杂性,并且尽量避免重复发明轮子。线程池是管理...
JUC(Java Concurrency Utilities)提供了高级同步工具,如Semaphore、CyclicBarrier和CountDownLatch,以及并发容器如ConcurrentHashMap,提升了多线程编程的便利性和性能。 总的来说,Java基础知识覆盖了从简单的...
《Chinese_AQS:为中国程序员解析AbstractQueuedSynchronizer》 在Java并发编程领域,AbstractQueuedSynchronizer(AQS)是一个至关重要的组件,它为实现锁和其他同步构建块提供了基础。然而,由于其复杂性和原始...
13. JUC中的并发工具包括Semaphore(信号量)、CyclicBarrier(回环栅栏)、CountDownLatch(计数器门闩)等。 14. ReadWriteLock提供了读写锁分离,提高并发性能;StampedLock提供了更细粒度的锁控制。 15. 通过...