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是一个同步辅助类.允许一个或多个线程等待其他线程 ...
随机推荐
- pyhanlp的安装
github 的官方地址:https://github.com/hankcs/pyhanlp conda install -c conda-forge jpype1 pip install pyhan ...
- Django的视图系统:View
一.CBV和FBV FBV:functoin based view,基于函数的view 我们之前写过的都是基于函数的view CBV:class based view,基于类的view 定义CBV: ...
- 隐马尔科夫模型(Hidden Markov Models) 系列之四
转自:http://blog.csdn.net/eaglex/article/details/6430389 前向算法(Forward Algorithm) 一.如果计算一个可观察序列的概率? 1 ...
- SAP CRM Product Interlinkage - Customer Product ID的一个例子
For detail technical introduction about relationship, please refer to this wiki. The relationship tr ...
- SqlServer数据库之递归
递归的实现比较简单,这里就直接贴SQL了. --简单创建一个用户表 CREATE TABLE User( UserID ,) , ParentUserID INT ) 假设这张有几千条数据,开始递归它 ...
- python基础-面向对象编程之多态
面向对象编程之多态以及继承.抽象类和鸭子类型三种表现形式 多态 定义:同一种类型的事物,不同的形态 作用: 多态也称之为"多态性".用于在不知道对象具体类型的情况下,统一对象调用方 ...
- 解决使用maven clean项目的时候报错,删除target文件夹失败
背景:jdk1.8 + maven3.5.2 问题描述: 我在使用maven clean项目的时候,celan 失败,报错的原因是删除项目下的target文件夹下面的文件失败 解决方法: 打开任务管理 ...
- 使用Deployment控制器创建Pods并使Service发布到外网可访问
由于NFS支持节点共同读取及写入,所以可使用Deployment控制器创建多个Pod,并且每一个Pod都共享同一个目录 k8s-master kubnet@hadoop2 volumes]$ vim ...
- UNITY Serializer 序列化 横向对比
UNITY Serializer 序列化 横向对比 关于序列化,无论是.net还是unity自身都提供了一定保障.然而人总是吃着碗里想着锅里,跑去github挖个宝是常有的事.看看各家大佬的本事.最有 ...
- 让天堂的归天堂,让尘土的归尘土——谈Linux的总线、设备、驱动模型
本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 公元1951年5月15日的国会听证上, ...