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接口 ...
随机推荐
- Python脚本破解图形验证码(tesserocr和pytesseract)
在学习之前,我们先了解OCR.tesseract.tesserocr.pytesseract和opencv这几个跟图片处理有关的库. OCR(Optical Character Recognition ...
- Docker镜像基本使用
使用 Docker 镜像 Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像. 获取镜像 docker pull [选项] [Docker Re ...
- Intel汇编语言程序设计学习-第二章 IA-32处理器体系结构-下
2.2 IA-32处理器体系结构 如前所述,IA-32是指始于Intel386直到当前最新的奔腾4的系列的处理器(额...这本书是什么时候写的啊,表示现在应该是I7啊),在IA-32的发展过程中,I ...
- 将大量ASCII码值转换成字符函数CHR()的小技巧
一.在学习命令执行漏洞的过程中,遇到以下情况: 当服务器上传不了马或者马被过滤的时候,我们可以迂回一下,通过执行写马命令到服务器,在服务器里面写马,该命令是通过ascii编码过的命令,防止被过滤. 1 ...
- MetInfo Password Reset Poisoning By Host Header Attack
if we know some user's email, the we will can reset the user's email by host header attack. The atta ...
- Mongodb安装配置以及在thinkphp中的使用
1.Mongodb安装 Mongodb安装参照此文档: https://www.runoob.com/mongodb/mongodb-window-install.html php的mongodb扩展 ...
- 1、requests基础
一.升级pip版本的命令 : python -m pip install --upgrade pip 二.requests安装 windows系统系cmd运行 pip install request ...
- DevEco Device Tool 2.1 Beta1在Hi3861开发板上可视化分析的体验
DevEco Device Tool迎来了2.1 Beta1,新版本有很多亮点.在上次"DevEco Device Tool 2.1 Beta1 的Hi3861在Windows平台的编译体验 ...
- k3d入门指南:在Docker中运行K3s
在本文中,我们将简单了解k3d,这是一款可让您在安装了Docker的任何地方运行一次性Kubernetes集群的工具,此外在本文中我们还将探讨在使用k3d中可能会出现的一切问题. 什么是k3d? k3 ...
- SpringBoot简单尝试
一.spring boot核心 配置在类路径下autoconfigure下(多瞅瞅) @SpringBootApplication里的重要注解(@Configuration,@EnableAutoCo ...