CountDownLatch源码
public class CountDownLatchExample1 {
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors1.newCachedThreadPool();
final CountDownLatch1 countDownLatch = new CountDownLatch1();
for (int i = ; i < ; i++) {
exec.execute(() -> {
try {
System.out.println("我我我我我我");
} catch (Exception e) {
} finally {
//state=0(不能向下减了,这个线程继续向下执行完,就不管CountDownLatch了,),减1之后!=0继续向下执行完。
//减1之后=0唤醒队列下一个节点。队列中只有main线程,实例化的线程不会去排队,只会执行完。
countDownLatch.countDown();// 为了保证必须减一,写在finally里面
}
});
}//线程在这里已经执行完了,
//state=0 main线程就向下执行,state!=0 main线程去排队。
countDownLatch.await(); // 减为0了才继续执行,这么多线程都减完了在一起走。
exec.shutdown(); // 线程次用完要关闭
}
}
//共享锁(不是锁,只是说多线程可以同时执行),没有锁的概念,没有公平非公平之分,
public class CountDownLatch1 {
private static final class Sync extends AbstractQueuedSynchronizer1 {
private static final long serialVersionUID = 4982264981922014374L; Sync(int count) {
setState(count);//设置state
} int getCount() {
return getState();
} // 这个方法会经常调用,如果state=0,证明可以唤醒等待线程了
protected int tryAcquireShared(int acquires) {
return (getState() == ) ? : -;
} // 尝试去释放锁,调用CountDown()方法会调用此方法,将state-1
protected boolean tryReleaseShared(int releases) {
for (;;) {// 死循环
int c = getState();
//一个是没减之前=0,一个是减1之后=0。没减之前=0就什么都不管了这个线程执行完算了。减1之后=0表示CountDownLatch变成了0就要唤醒主线程继续向下走。
if (c == )
return false;//state=0不能向下减了,这个线程继续向下执行完,就不管CountDownLatch了,
int nextc = c-;
if (compareAndSetState(c, nextc))//state减1失败继续死循环,
return nextc == ;//true:唤醒队列下一个节点(已经减完了,唤醒main线程),false:减1后继续向下执行完
}
}
} private final Sync sync; public CountDownLatch1(int count) {
if (count < ) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
} public void await() throws InterruptedException {
sync.acquireSharedInterruptibly();//state=0 main线程就向下执行,state!=0 mian线程去排队。
} public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(, unit.toNanos(timeout));
} public void countDown() {
//state=0(不能向下减了,这个线程继续向下执行完,就不管CountDownLatch了,),减1之后!=0继续向下执行完,不唤醒main线程。
//减1之后=0唤醒队列下一个节点。队列中只有main线程,实例化的线程不会去排队,只会执行完。
sync.releaseShared();
} public long getCount() {
return sync.getCount();
} public String toString() {
return super.toString() + "[Count = " + sync.getCount() + "]";
}
}
CountDownLatch源码的更多相关文章
- Java - "JUC" CountDownLatch源码分析
Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例 CountDownLatch简介 CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前 ...
- CountDownLatch源码浅析
Cmd Markdown链接 CountDownLatch源码浅析 参考好文: JDK1.8源码分析之CountDownLatch(五) Java并发之CountDownLatch源码分析 Count ...
- Java并发工具类CountDownLatch源码中的例子
Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...
- CountDownLatch 源码分析
CountDownLatch 源码分析: 1:CountDownLatch数据结构 成员变量 Sync类型对象 private final Sync sync; Sync是继承AQS的一个类,Coun ...
- 多线程进阶——JUC并发编程之CountDownLatch源码一探究竟
1.学习切入点 JDK的并发包中提供了几个非常有用的并发工具类. CountDownLatch. CyclicBarrier和 Semaphore工具类提供了一种并发流程控制的手段.本文将介绍Coun ...
- CountDownLatch源码解析
一.CountDownLatch介绍 CountDownLatch是在jdk1.5被引入的,它主要是通过一个计数器来实现的,当在初始化该类的构造函数时,会事先传入一个状态值,之后在执行await方法后 ...
- CountDownLatch 源码解析—— countDown()
上一篇文章从源码层面说了一下CountDownLatch 中 await() 的原理.这篇文章说一下countDown() . public void countDown() { //CountDow ...
- CountDownLatch 源码解析—— await()
上一篇文章说了一下CountDownLatch的使用方法.这篇文章就从源码层面说一下await() 的原理. 我们已经知道await 能够让当前线程处于阻塞状态,直到锁存器计数为零(或者线程中断). ...
- Java并发——结合CountDownLatch源码、Semaphore源码及ReentrantLock源码来看AQS原理
前言: 如果说J.U.C包下的核心是什么?那我想答案只有一个就是AQS.那么AQS是什么呢?接下来让我们一起揭开AQS的神秘面纱 AQS是什么? AQS是AbstractQueuedSynchroni ...
- concurrent(五)同步辅助器CountDownLatch & 源码分析
参考文档: https://blog.csdn.net/zxdfc/article/details/52752803 简介 CountDownLatch是一个同步辅助类.允许一个或多个线程等待其他线程 ...
随机推荐
- Razor Page中的AJAX
1.由于Razor Pages自带提供防伪令牌/验证,用来防止跨站点请求伪造(称为XSRF或CSRF),所以和MVC框架中API使用方式有稍许的不同. 2.所以在我们使用Razor Pages中的fo ...
- webapi 集成NLog
参考项目代码:SwaggerDemoApi 安装 打开nuget管理器--->搜索nlog,安装箭头所指的两个文件到你的项目中,config安装到你的API项目即可,nlog文件安装到你用得到n ...
- asp.net mvc ViewBag常用操作
1.视图获取json类型数据 var str = '@(ViewBag.loginInfoList)'; if ($.trim(str).length>0) { re = new RegExp( ...
- SpringBoot 整合MyBatis 统一配置bean的别名
所谓别名, 就是在mappper.xml配置文件中像什么resultType="xxx" 不需要写全限定类名, 只需要写类名即可. 配置方式有两种: 1. 在 applicatio ...
- 深浅赋值+orm操作+Django-admin简单配置
知识点 深浅copy 浅值深id orm操作 ManyToManyField 虚拟字段 告诉Django orm 自动帮你创建第三张表 查询的时候可以借助该字段跨表 外键属性可赋值外联对象 Model ...
- iis url 重写
1.选择网站-找到有测url 重写 :2:选中它,在右上角有一个打开功能,点击打开 3.依然在右上角,点击添加规则 4:选择第一个,空白规则 名称随便输入,我们通常有这样一个需求,就是.aspx 后缀 ...
- vue+element省市县的二级联动功能
项目中有选择省市县的需求,先选择省,再选择县 解决这个需求也不是很难,总体思路就是看后端接口, 一般后端接口都是请求参数为 0 返回省的数据,不为 0 的话返回相对应的市的数据 template代码: ...
- vmware关闭嘟嘟嘟嘟警告
在使用VMware workstation时,安装的windows或者Linux遇到错误操作时,会发生刺耳的嘟嘟声.如何关闭呢?在VMware虚拟机windows系统中的命令提示符处键入以下命令, 然 ...
- 运用软链接,解决NBU默认安装目录空间不足
建立软链接实例: 例如 /usr 剩余空间5G,/opt剩余空间100G 提前在通过如下命令在/opt 目录下创建openv文件夹 mkdir -p /opt/openv 然后进入 /opt/open ...
- NLP中的预训练语言模型(一)—— ERNIE们和BERT-wwm
随着bert在NLP各种任务上取得骄人的战绩,预训练模型在这不到一年的时间内得到了很大的发展,本系列的文章主要是简单回顾下在bert之后有哪些比较有名的预训练模型,这一期先介绍几个国内开源的预训练模型 ...