并发库应用之九 & 到时计数器CountDownLatch应用

时间:2021-10-24 12:03:08

  申明:CountDownLatch好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行。

  java.util.concurrent.CountDownLatch

  一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier ( 请查看我的另外一篇博客:并发库应用之八 & 循环路障CyclicBarrier应用 )

  CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。用 N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。

  CountDownLatch 的一个有用特性是,它不要求调用 countDown 方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个 await。

对应构造方法摘要:

  CountDownLatch(int count)           构造一个用给定计数初始化的 CountDownLatch

方法摘要:

  void  await()                      使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断

  boolean  await(long timeout, TimeUnit unit)    使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间

  void  countDown()                       递减锁存器的计数,如果计数到达零,则释放所有等待的线程

  long  getCount()                          返回当前计数

  String  toString()                          返回标识此锁存器及其状态的字符串

案例应用:

  可以实现一个人(也可以是多个人)等待其他所有人都来通知他,这犹如一个计划需要多个领导都签字后才能继续向下实施。还可以实现一个人通知多个人的效果。
类似于生活当中的百米赛跑运动,当裁判一声令下,运动员同时开始奔跑。那么我们下面就用它来实现百米赛跑游戏,上代码:

 import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class CountdownLatchTest { public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
//裁判发布命令的计数器,计数器为0好似裁判开起跑枪,运动员就开跑
final CountDownLatch cdOrder = new CountDownLatch(1);
//预定义有3个运动员,运动员跑到终点的计数器,为0裁判宣布结果
final CountDownLatch cdAnswer = new CountDownLatch(3);
for (int i = 0; i < 3; i++) { //产生3个运动员
Runnable runnable = new Runnable() {
public void run() {
try {
System.out.println(String.format("线程【%s】准备接受起跑命令", Thread.currentThread().getName()));
cdOrder.await(); System.out.println(String.format("线程【%s】已接受命令--冲刺", Thread.currentThread().getName()));
Thread.sleep((long) (Math.random() * 5000)); //随机在5s内休眠 System.out.println(String.format("线程【%s】回应命令结果--达到终点", Thread.currentThread().getName()));
cdAnswer.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
//主线程,开始计数器为1正在阻塞,由主线程出发减1动作,之后3个子线程接收到命令开始冲刺
try {
Thread.sleep((long) (Math.random() * 5000)); //随机在5s内休眠 System.out.println(String.format("*裁判*线程【%s】准备开始发布命令,冲刺开枪", Thread.currentThread().getName()));
cdOrder.countDown(); System.out.println(String.format("*裁判*线程【%s】已经完成发布命令,等待比赛结果", Thread.currentThread().getName()));
cdAnswer.await(); System.out.println(String.format("*裁判*线程【%s】已经收到所有回应,宣布比赛结束", Thread.currentThread().getName()));
} catch (Exception e) {
e.printStackTrace();
}
service.shutdown();
}
}

运行以上代码打印的效果如下所示:

  并发库应用之九 & 到时计数器CountDownLatch应用

提示:欢迎继续参看我相关的下一篇博客:并发库应用之十 & 多线程数据交换Exchanger应用

并发库应用之九 & 到时计数器CountDownLatch应用的更多相关文章

  1. 并发库应用之八 &amp&semi; 循环路障CyclicBarrier应用

    JDK包位置:java.util.concurrent.CyclicBarrier 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及 ...

  2. JAVA并发编程之倒计数器CountDownLatch

    CountDownLatch 的使用场景:在主线程中开启多线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后汇总返回结果. 我把源码中的英文注释全部删除,写上自己的注释.就剩下 70 行不到的 ...

  3. Java线程新特征——Java并发库

    一.线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...

  4. java--加强之 Java5的线程并发库

    转载请申明出处:http://blog.csdn.net/xmxkf/article/details/9945499 01. 传统线程技术回顾 创建线程的两种传统方式: 1.在Thread子类覆盖的r ...

  5. Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier

    Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...

  6. Java复习——多线程与并发库

    开启一个线程 实现一个线程的方式有两种:继承Thread类.实现Runnable接口(也存在说三种的情况,第三种是使用线程并发库中的线程池创建一个线程).这两种方法都需要重写Run方法,具体的线程逻辑 ...

  7. Java多线程与并发库高级应用-java5线程并发库

    java5 中的线程并发库 主要在java.util.concurrent包中 还有 java.util.concurrent.atomic子包和java.util.concurrent.lock子包 ...

  8. java并发库&lowbar;并发库知识点整理

    并发库(java.util.concurrent)中的工具数不胜数,那么我们梳理一下线程并发库中重要的一些常用工具: 1.

  9. 线程高级应用-心得8-java5线程并发库中同步集合Collections工具类的应用及案例分析

    1.  HashSet与HashMap的联系与区别? 区别:前者是单列后者是双列,就是hashmap有键有值,hashset只有键: 联系:HashSet的底层就是HashMap,可以参考HashSe ...

随机推荐

  1. myeclipse &plus; tomcat 项目自动部署

    在MyEclipse中设置项目的自动部署需要综合考虑两个方面: 1是MyEclipse本身,通过主菜单中project->auto ,另一个就是tomcat配置文件.配置文件包括 conf 下的 ...

  2. BZOJ2095 &lbrack;Poi2010&rsqb;Bridges

    首先二分答案...然后这张图变成了有一些有向边,有一些无向边 然后就是混合图欧拉回路的判断 我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度 对于混合图...先不管有向边,把无向边 ...

  3. iOS 国际化多语言设置 xcode7

    iOS 国际化多语言设置 方式一: 1. 在storyboard中创建好UI,然后在 project 里面  Localizables 栏目里面,添加你需要的语言:默认是Englist; 比如这里我添 ...

  4. 单表多次join的sql

    select o1.emp_name as 员工姓名1 , o2.emp_name as 员工姓名2 from tableTest join employee o1 on tabletest.[Emp ...

  5. Javascript注意事项一【防止浮点数溢出】

    num = 0.1+0.2; //0.30000000000000004 a = (1+2)/10; //0.3(浮点数中的整数运算时精确的)

  6. selenium webdriver&lpar;3&rpar;---操作页面对象

    页面对象的相关操作可以通过接口文件org.openqa.selenium.WebElement查看,本文只是对象接口的使用方式,具体的实现方式在org.openqa.selenium.remote.R ...

  7. UVA 10806 Dijkstra&comma; Dijkstra&period;

    题意: 从起点走到终点,然后从终点走到起点,其中不能同时走过相同的一条边,问你最小路径长度.先输入终点n,起点为1,接下来输入m,代表有m条边.每条边由起点,终点,长度组成. 分析: 求最小长度,还限 ...

  8. js&comma;this&comma;constrct &comma;prototype

    这一章我们将会重点介绍JavaScript中几个重要的属性(this.constructor.prototype), 这些属性对于我们理解如何实现JavaScript中的类和继承起着至关重要的作 th ...

  9. C 语言统计关键字出现次数

    #include <stdio.h> #include <ctype.h> #include <string.h> #define NKEYS (sizeof ke ...

  10. visibility&colon; hidden和 display&colon; none的区别

    visibility: hidden----将元素隐藏,但是在网页中该占的位置还是占着. display: none----将元素的显示设为无,即在网页中不占任何的位置.