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源码的更多相关文章

  1. Java - "JUC" CountDownLatch源码分析

    Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例 CountDownLatch简介 CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前 ...

  2. CountDownLatch源码浅析

    Cmd Markdown链接 CountDownLatch源码浅析 参考好文: JDK1.8源码分析之CountDownLatch(五) Java并发之CountDownLatch源码分析 Count ...

  3. Java并发工具类CountDownLatch源码中的例子

    Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...

  4. CountDownLatch 源码分析

    CountDownLatch 源码分析: 1:CountDownLatch数据结构 成员变量 Sync类型对象 private final Sync sync; Sync是继承AQS的一个类,Coun ...

  5. 多线程进阶——JUC并发编程之CountDownLatch源码一探究竟

    1.学习切入点 JDK的并发包中提供了几个非常有用的并发工具类. CountDownLatch. CyclicBarrier和 Semaphore工具类提供了一种并发流程控制的手段.本文将介绍Coun ...

  6. CountDownLatch源码解析

    一.CountDownLatch介绍 CountDownLatch是在jdk1.5被引入的,它主要是通过一个计数器来实现的,当在初始化该类的构造函数时,会事先传入一个状态值,之后在执行await方法后 ...

  7. CountDownLatch 源码解析—— countDown()

    上一篇文章从源码层面说了一下CountDownLatch 中 await() 的原理.这篇文章说一下countDown() . public void countDown() { //CountDow ...

  8. CountDownLatch 源码解析—— await()

    上一篇文章说了一下CountDownLatch的使用方法.这篇文章就从源码层面说一下await() 的原理. 我们已经知道await 能够让当前线程处于阻塞状态,直到锁存器计数为零(或者线程中断). ...

  9. Java并发——结合CountDownLatch源码、Semaphore源码及ReentrantLock源码来看AQS原理

    前言: 如果说J.U.C包下的核心是什么?那我想答案只有一个就是AQS.那么AQS是什么呢?接下来让我们一起揭开AQS的神秘面纱 AQS是什么? AQS是AbstractQueuedSynchroni ...

  10. concurrent(五)同步辅助器CountDownLatch & 源码分析

    参考文档: https://blog.csdn.net/zxdfc/article/details/52752803 简介 CountDownLatch是一个同步辅助类.允许一个或多个线程等待其他线程 ...

随机推荐

  1. pyhanlp的安装

    github 的官方地址:https://github.com/hankcs/pyhanlp conda install -c conda-forge jpype1 pip install pyhan ...

  2. Django的视图系统:View

    一.CBV和FBV FBV:functoin based view,基于函数的view 我们之前写过的都是基于函数的view CBV:class based view,基于类的view 定义CBV: ...

  3. 隐马尔科夫模型(Hidden Markov Models) 系列之四

    转自:http://blog.csdn.net/eaglex/article/details/6430389 前向算法(Forward Algorithm) 一.如果计算一个可观察序列的概率?   1 ...

  4. SAP CRM Product Interlinkage - Customer Product ID的一个例子

    For detail technical introduction about relationship, please refer to this wiki. The relationship tr ...

  5. SqlServer数据库之递归

    递归的实现比较简单,这里就直接贴SQL了. --简单创建一个用户表 CREATE TABLE User( UserID ,) , ParentUserID INT ) 假设这张有几千条数据,开始递归它 ...

  6. python基础-面向对象编程之多态

    面向对象编程之多态以及继承.抽象类和鸭子类型三种表现形式 多态 定义:同一种类型的事物,不同的形态 作用: 多态也称之为"多态性".用于在不知道对象具体类型的情况下,统一对象调用方 ...

  7. 解决使用maven clean项目的时候报错,删除target文件夹失败

    背景:jdk1.8 + maven3.5.2 问题描述: 我在使用maven clean项目的时候,celan 失败,报错的原因是删除项目下的target文件夹下面的文件失败 解决方法: 打开任务管理 ...

  8. 使用Deployment控制器创建Pods并使Service发布到外网可访问

    由于NFS支持节点共同读取及写入,所以可使用Deployment控制器创建多个Pod,并且每一个Pod都共享同一个目录 k8s-master kubnet@hadoop2 volumes]$ vim ...

  9. UNITY Serializer 序列化 横向对比

    UNITY Serializer 序列化 横向对比 关于序列化,无论是.net还是unity自身都提供了一定保障.然而人总是吃着碗里想着锅里,跑去github挖个宝是常有的事.看看各家大佬的本事.最有 ...

  10. 让天堂的归天堂,让尘土的归尘土——谈Linux的总线、设备、驱动模型

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 公元1951年5月15日的国会听证上, ...