JUC下工具类CountDownLatch用法以及源码理解
CountDownLoatch是JUC下一个用于控制计数的计数器,比如我需要从6开始计数,每个线成运行完之后计数减一,等计数器到0时候开始执行其他任务。
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t结束");
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println("开始执行新任务");
}
现在让我们来看下CountDownLoach的底层源码
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) {
return (getState() == 0) ? 1 : -1;
} 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;
}
}
} private final Sync sync;
这里最重要的是这个tyrReleaseShared方法,CountDownLatch也是实现了AQS机制,通过state去判断资源知否被占用。当我们使用countDow函数去减1时,会触发releaseShared方法,这个方法的参数时每次减的次数,默认是1
public void countDown() {
sync.releaseShared(1);
}
我们点进去看看这个方法是如何实现的
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
这个方法调用了AQS的releaseShared,他会先去尝试减一,判断是否减一成功
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;
}
}
这里使用了CAS自旋机制对state(我们这里是6)进行减1,如果自旋成功就会返回true即6一个一个减最后变成0,就会执行下面的doReleaseShared方法
private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue; // loop to recheck cases
unparkSuccessor(h);
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}
这里使用了LockSupport相关的加锁解锁,unpark有关这个我会在之后有空的时候进行解析,通过对AQS任务队列进行判断,是否只有头节点和尾节点,这个任务队列里面头节点并不是真正的任务,而是为了初始化方便操作的哨兵节点,然后对第一个任务节点进行操作,就是我们这6步操作,每次减一作为一个任务进行释放(我自己认为的)。
这是我第一次发帖子希望大家多多支持,准备秋招了,争取大厂上岸,如果帖子里有错误希望大家积极提出来
JUC下工具类CountDownLatch用法以及源码理解的更多相关文章
- Java并发工具类CountDownLatch源码中的例子
Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...
- 多线程学习笔记六之并发工具类CountDownLatch和CyclicBarrier
目录 简介 CountDownLatch 示例 实现分析 CountDownLatch与Thread.join() CyclicBarrier 实现分析 CountDownLatch和CyclicBa ...
- 同步工具类 CountDownLatch 和 CyclicBarrier
在开发中,一些异步操作会明显加快执行速度带来更好的体验,但同时也增加了开发的复杂度,想了用好多线程,就必须从这些方面去了解 线程的 wait() notify() notifyall() 方法 线程异 ...
- 业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份
业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份 WinForm酒店管理软件--框架这篇随笔可以说是我写的最被大家争议的随笔,一度是支持和反对是一样的多.大家对我做的这个行业 ...
- Java并发工具类 - CountDownLatch
Java并发工具类 - CountDownLatch 1.简介 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面 http: ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
- Spring源码分析之IOC的三种常见用法及源码实现(二)
Spring源码分析之IOC的三种常见用法及源码实现(二) 回顾上文 我们研究的是 AnnotationConfigApplicationContext annotationConfigApplica ...
- JUC中Lock和ReentrantLock介绍及源码解析
Lock框架是jdk1.5新增的,作用和synchronized的作用一样,所以学习的时候可以和synchronized做对比.在这里先和synchronized做一下简单对比,然后分析下Lock接口 ...
随机推荐
- 通过修改EIP寄存器实现强行跳转并且注入DLL到目标进程里
/* 描述 功能:通过修改EIP寄存器实现32位程序的DLL注入(如果是64位,记得自己对应修改汇编代码部分) 原理: 挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,然后把相关的指令机器 ...
- RSS阅读器 - Reeder
苹果生态圈内最佳RSS阅读器 - Reeder 好用就完事了
- 【ECharts】报表联动,动态数据设计
说明: 数据没有拉取后台数据,仅仅前端模拟数据,Copy即可有效果.联动后台时,使用异步获取数据即可.鼠标点击,动态展示点击项的数据.有关更多实例,请移步到echarts官网查看. 成果展示: 相关代 ...
- layui中时间插件laydate的使用
1.加载layui.js 2.html部分 <div class="layui-inline"> <label class="layui-form-la ...
- HDU - 2091 空心三角形 水题,但是有点坑...
空心三角形 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- ConcurrentHashMap源码解读三
今天首先讲解helpTransfer方法 final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) ...
- 矩阵旋转-Eigen应用(QTCreator编辑器)
* { font-family: "Tibetan Machine Uni", "sans-serif", STFangSong; outline: none ...
- Spring MVC工作原理及源码解析(二)DispatcherServlet实现原理及源码解析
1.DispatcherServlet 处理流程 从上一篇文章中Spring MVC原理图中我们可以看出:DispatcherServlet 在 Spring MVC框架 中处于核心位置,它负责协调和 ...
- (转)netcore原生websocket客户端写法(ClientWebSocket)
代码: using System; using System.Net.WebSockets; using System.Text; using System.Threading; using Syst ...
- 异步阻塞,Manager模块,线程
一.异步阻塞 1.并没有按照执行顺序等待结果 2.而是所有的任务都在异步执行着 3.但是我要的结果又不知道谁的结果先来,谁先结束我就先取谁的结果 很明显的异步,大家都相互执行着(异步过程),谁先结束我 ...