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是一个同步辅助类.允许一个或多个线程等待其他线程 ...
随机推荐
- 有哪位大侠操作过NPOI生成word文档,如何设置页眉页脚距离顶部和底部距离?
#region 1.创建文档(页眉.页脚) XWPFDocument doc = new XWPFDocument(); //页面设置 A4:w=11906 h=16838 doc.Document. ...
- 安全漏洞系列(二)---站点信息侦测(C# MVC)
参考地址:https://jingyan.baidu.com/article/77b8dc7fa657c26174eab631.html 概述:站点信息侦测漏洞会检测到用的版本信息等,然后借此进行一些 ...
- Windows Server2008R2,ServerWin2012 R2设置自动登录注册表配置
serverWin2008 R2 2012自动登录一般是通过control userpasswords2 命令修改,其实注册表修改更简单.复制以下保存为xx.reg文件导入即可即可. Windows ...
- 基于注解的SpringAOP源码解析(二)
在上篇文章 中我们搭建了一个阅读源码的demo工程,然后简单介绍了一下@EnableAspectJAutoProxy注解,这个注解最重要的功能就是为向Spring中注入了一个beanAnnotatio ...
- 【转】解决Oracle 11g在用EXP导出时,空表不能导出
一.问题原因: 11G中有个新特性,当表无数据时,不分配segment,以节省空间 .insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segme ...
- 【MySQL】自增步长调整
mysql> show variables like '%increment%'; +-----------------------------+-------+ | Variable_name ...
- nginx 日志问题(\x22)
nginx 日志问题(\x22) 问题: 1.request_body中含有中文时,nginx日志会转换为十六进制. 2.nginx记录问题 POST /xxxxx HTTP/1.1|200|4266 ...
- 记一次wsl上的pip3安装失败问题 The following packages were automatically installed and are no longer required:
转载请注明来源.https://www.cnblogs.com/sogeisetsu/.然后我的CSDNhttps://blog.csdn.net/suyues/article/details/103 ...
- udp,select超时和recvfrom收不到数据原因
wirshark抓包,发现有数据.但是select超时,直接recvfrom又失败. 代码中需要改进:select超时后,会移除fd_set集合中超时的那个句柄,所以每次要重新进行FD_SET,然后再 ...
- Spring-Data-Redis 入门学习
Spring-Data-Redis 入门学习 参考文章: https://www.jianshu.com/p/4a9c2fec1079 导入 redis 相关依赖 <dependency> ...