视频课程
小黑屋思过中,禁止观看!
评论并刷新后可见

您需要在视频最下面评论并刷新后,方可查看完整视频

视频课程
立即观看
付费视频

您支付费用,方可查看完整视频

¥{{user.role.value}}
课程视频
开始学习
会员专享

视频合集

CountDownLatch核心源码解析

  • 课程笔记
  • 问答交流

之前我谈到过ReentrantLock是基于AQS的独占锁来实现的,今天主要来谈谈AQS的另外一种锁:共享锁的实现。

为了助大家掌握好CountDownLatch,本节课我会重点讲解以下5点:

1.CountDownLatch简介

2.CountDownLatch的核心成员

3.CountDownLatch的源码解析

4.CountDownLatch的应用场景

5.CountDownLatch的总结

CountDownLatch

CountDownLatch是java的JUC并发包里的一个工具类,可以理解为一个倒计时器,用于当某些任务执行完后,再执行其他任务的场景。

例如:老板开会,只有等所有人到齐了才能开会。

CountDownLatch核心源码解析-mikechen

比如有一个主线程A(老板),它要等待其他4个子线程(员工)执行完成(到达会议室)之后才能执行(开会),此时就可以利用CountDownLatch来实现这种功能了。

CountDownLatch核心源码解析-mikechen

CountDownLatch的实现原理

CountDownLatch核心源码解析-mikechen

评论交流
  1. 路正银

    1、实现原理:
    CountDownLatch是用AQS实现的,使用AQS的state变量来存放计数器的值。在调用CountDownLatch的构造函数时,
    会调用内部类Sync的构造函数将值赋给state变量,当多个线程调用countdown方法时实际是使用CAS递减state变量的值;当线程调用await方法后当前线程会被放入AQS阻塞队列等待计数器为0时返回,即其他所有线程都调用了countdown方法时。最后,当计数器的值变为0时,当前线程还会调用AQS的doReleasedShared()方法激活调用await()方法而被阻塞的线程。
    2、核心方法:
    CountDownLatch构造方法(创建计数器)
    await(阻塞队列)
    countDown(计数器递减)
    3、使用场景:
    一个任务包含多个任务,主任务需要所有子任务全部完成之后才能开始运行。

  2. JansenZhang

    1.CountDownLatch继承AQS,使用了AQS的共享锁模式。使用state作为计数器,CLH队列实现线程等待。在初始化CDL的时候会定义计数器的值,每次调用countDown()都会使state-1,当state==0的时候会唤醒所有的await()的线程。
    2.CDL的核心方法有:
    CDL(int count) 构造函数,在构造的时候设置state的初始值;
    countDown() 使state – 1,调用releaseShared(1);
    await() 获取锁,如果没有获取成功,则将当前线程包装成Node加入CLH队列尾部,然后进行自旋获取锁,直到成功,调用acquireSharedInterruptibly()。
    3.使用场景:
    1⃣️在一个方法里需要组装各个接口返回的数据,可以在每个线程里各自获取各自接口的数据,主线程await(),等主线程获取到锁以后,再进行数据的组装;
    2⃣️在测试时模拟并发请求,设置CDL(1),所有子线程全部await(),等所有子线程初始化完毕以后,主线程countDown()。