1. 倒计时门闩同步器

倒计时门闩会导致一条或多条线程在“门口”一直等待,直到另一条线程打开这扇门,线程才得以继续运行。它是由一个计数变量和两个操作组成的,这两个操作分别是“导致一条线程等待直到计数变为0”以及“递减计数变量”。

类java.util.concurrent.CountDownLatch实现了倒计时门闩同步器。

应用场景:比如流水线,后面的工序必须等到前面的工序做完之后才能继续做。

2. 常用方法

(1)CountDownLatch(int count)

倒计时门闩同步器的构造方法,通过参数count指定计数个数,来初始化一个CountDownLatch的实例。当count的值是负数,该方法会抛出java.lang.IllegalArgumentException。

(2)void await()

除非线程被中断,否则强制调用线程一直等到计数倒数到0。线程被中断时会抛出java.lang.InterruptedException。当count是0时,该方法立即返回。

(3)boolean await(long timeout, TimeUnit unit)

除非线程被中断,否则强制调用线程一直等到计数倒数至0或者以Unit作为时间单元的timeout超时。线程被中断时会抛出java.lang.InterruptedException。当count是0时,该方法立即返回ture;当超时等待时间时,返回fasle.

(4)void countDown()

递减计数,当计数降至0时,释放所有等待线程。当该方法被调用时count已经为0,那么什么也不会发生。

(5)long getCount()

返回当前的计数,该方法对于测试和调试很有用。

(6)String toString()

返回一条标识这个门闩及其状态的字符串。状态是用中括号括住的字符串常量“Count = ”拼接上当前的计数。

3.

(1)倒计时门闩示例1

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;//倒计时门闩同步器简单实例
public class CountDownLatchDemo1 {public static void main(String[] args){CountDownLatch countDownLatch = new CountDownLatch(3);Runnable r = new Runnable(){@Overridepublic void run(){System.out.println(Thread.currentThread().getName()+": latch count is " + countDownLatch.getCount());countDownLatch.countDown(); //递减计数System.out.println(Thread.currentThread().getName()+": after countDown, latch count is " + countDownLatch.getCount());}};ExecutorService executorService = Executors.newFixedThreadPool(3);System.out.print("before latch await\n");for(int i = 0; i < 3; i++){executorService.execute(r);}try {countDownLatch.await();             //只有当计数倒数至0时,后面的主线程才会继续执行。} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("after latch await");executorService.shutdownNow();}
}

运行结果:

before latch await
pool-1-thread-2: latch count is 3
pool-1-thread-2: after countDown, latch count is 2
pool-1-thread-1: latch count is 3
pool-1-thread-1: after countDown, latch count is 1
pool-1-thread-3: latch count is 3
pool-1-thread-3: after countDown, latch count is 0
after latch await

默认主线程首先创建了一个倒计时门闩,这个门闩会使得默认主线程等待所有的工作线程全部结束再执行。

默认主线程接下来创建了一个带有run()方法的runnable,它会被后续创建的工作线程执行。在这个run()方法中,先打印在countDown递减计数之前的计数值,然后开始递减计数,最后再打印一次countDown递减计数之后的计数值。

创建好runnable之后,然后创建了一个固定线程数为3的线程池,先打印了一条消息“before latch await”,再依次把runnable传入线程池中。这一动作会启动线程运行run()方法。

接着调用await()方法,主线程只能等到count递减至0时,才能继续往下执行,也就是输出“after latch await ”。

(2)倒计时门闩示例2

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class CountDownLatchDemo2 {final static int NThreads = 3;public static void main(String[] args){final CountDownLatch startSignal = new CountDownLatch(1);final CountDownLatch doneSignal = new CountDownLatch(3);Runnable r = new Runnable() {@Overridepublic void run(){try {report("entered run()");startSignal.await();   //等待主线程就绪report("doing work");Thread.sleep((int)(Math.random()*1000)); //模拟工作过程doneSignal.countDown();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}void report(String s){System.out.println(System.currentTimeMillis()+":"+Thread.currentThread()+ ":" + s);}};ExecutorService executorService = Executors.newFixedThreadPool(NThreads);for(int i = 0; i < NThreads; i++){executorService.execute(r);}try {System.out.println("main thread doing something");Thread.sleep(1000);  //模拟执行其他工作,得以让所有工作线程依次执行run()方法,进而调用startSignal.await()startSignal.countDown();System.out.println("main thread doing something else");doneSignal.await();  //等待所有线程结束,即计数递减到0,才能关闭executorServiceexecutorService.shutdownNow();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

运行结果:

main thread doing something
1543026469731:Thread[pool-1-thread-2,5,main]:entered run()
1543026469731:Thread[pool-1-thread-3,5,main]:entered run()
1543026469731:Thread[pool-1-thread-1,5,main]:entered run()
main thread doing something else
1543026470733:Thread[pool-1-thread-3,5,main]:doing work
1543026470733:Thread[pool-1-thread-1,5,main]:doing work
1543026470733:Thread[pool-1-thread-2,5,main]:doing work

默认主线程首先创建了一对倒计时门闩。这个startSignal门闩会在默认主线程就绪之前禁止任何工作线程线程执行,而doneSignal门闩会使得默认主线程等待所有的工作线程全部结束再执行接下来的。

Java并发——倒计时门闩相关推荐

  1. java多线程 门闩_Java线程与并发编程实践----同步器(倒计时门闩,同步屏障)...

    Java提供的synchronized关键字对临界区进行线程同步访问.由于基于synchronized很难 正确编写同步代码,并发工具类提供了高级的同步器.倒计时门闩(countdown latch) ...

  2. Java并发编程工具

    第1节:什么是java并发编程.mp4 第2节:并发工具类有哪些.mp4 第3节:课程文档资料.pdf 第4节:线程池介绍.mp4 第5节:增减线程的时机.mp4 第6节:keepAliveTime和 ...

  3. 学习笔记:Java 并发编程⑥_并发工具_JUC

    若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 配套资料: ...

  4. 【Java 并发编程】CountDownLatch 简介

    文章目录 I CountDownLatch 概念 II CountDownLatch 使用流程 III CountDownLatch API 简介 I CountDownLatch 概念 1. 概念 ...

  5. Java并发编程面试题(2020最新版)

    转载自  Java并发编程面试题(2020最新版) 基础知识 并发编程的优缺点 为什么要使用并发编程(并发编程的优点) 充分利用多核CPU的计算能力:通过并发编程的形式可以将多核CPU的计算能力发挥到 ...

  6. Java并发相关知识(多线程、锁、容器、工具)

    目录 一.基础知识 线程之间如何通信? Java内存模型 内存屏障 顺序一致性 CAS实现原理 原子操作 volatile synchronized 实现原理 什么是锁 原子操作类说明 高性能原子类 ...

  7. java并发编程之再学习

    java并发基础 Callable 首先我们来理一理Future和Runable的关系: public class FutureTask<V> implements RunnableFut ...

  8. 【搞定Java并发编程】第24篇:Java中的并发工具类之CountDownLatch

    上一篇:Java中的阻塞队列 BlockingQueue 详解 本文目录: 1.CountDownLatch的基本概述 2.CountDownLatch的使用案例 3.CountDownLatch的源 ...

  9. Java并发编程系列学习_CountDownLatch倒计时器CyclicBarrier循环栅栏

    一.倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join方 ...

最新文章

  1. SIM300实现GPRS上网
  2. MUI:字符串和json数据的相互转换
  3. python 字符匹配_python 中如何匹配字符串
  4. Ubuntu 答疑:Ubuntu 添加和删除用户具体步骤及进程被占用的解决方式
  5. java中关于重写的说法_Java中有关“重载”和“重写”的说法正确的是()
  6. FPGA实现按键消抖及短时间按键和长时间按键不同动作
  7. mysql中datetime有带时区_当服务器时区不是UTC时,从Java中检索来自MySQL的UTC DATETIME字段...
  8. java basic data type,DataStage Basic学习笔记
  9. 什么是SEO?SEO的区别在哪里?
  10. SINR, RSRP, CQI 关系
  11. tinymind 书法文字识别
  12. u8的汇兑损益的计算公式_C程序计算损益
  13. 【线性代数】共轭转置矩阵
  14. python html_在python中下载html?
  15. OE分布式智能云生态
  16. 恋词题源报刊Unit5背诵
  17. MDK5(Keil5)新建一个新空白工程模板
  18. 戴尔服务器重装系统bios设置,dell服务器bios设置方法
  19. JPA配置不生成外键
  20. 数据结构与算法JAVA语言描述第六章部分课后习题参考答案

热门文章

  1. davinci DM365-DM368开发攻略—linux-2.6.32移植
  2. C++ Primer 第五版 课后章节练习答案 第一、二章
  3. 教你简单去除 Office 2007 盗版提示
  4. 自己动手制作植物大战僵尸简单修改器(3)
  5. UE4 Gif图插件
  6. 从搜索引擎结果来看用户体验
  7. Bootstrap框架常用组件
  8. 单目相机(Mono camera)在MATLAB中的表示与实例
  9. 招行每日答题赢积分【题库】
  10. MacType - 美化 Windows 字体