并发库应用之九 & 到时计数器CountDownLatch应用
申明: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();
}
}
运行以上代码打印的效果如下所示:

提示:欢迎继续参看我相关的下一篇博客:并发库应用之十 & 多线程数据交换Exchanger应用
并发库应用之九 & 到时计数器CountDownLatch应用的更多相关文章
- 并发库应用之八 & 循环路障CyclicBarrier应用
JDK包位置:java.util.concurrent.CyclicBarrier 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及 ...
- JAVA并发编程之倒计数器CountDownLatch
CountDownLatch 的使用场景:在主线程中开启多线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后汇总返回结果. 我把源码中的英文注释全部删除,写上自己的注释.就剩下 70 行不到的 ...
- Java线程新特征——Java并发库
一.线程池 Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...
- java--加强之 Java5的线程并发库
转载请申明出处:http://blog.csdn.net/xmxkf/article/details/9945499 01. 传统线程技术回顾 创建线程的两种传统方式: 1.在Thread子类覆盖的r ...
- Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier
Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...
- Java复习——多线程与并发库
开启一个线程 实现一个线程的方式有两种:继承Thread类.实现Runnable接口(也存在说三种的情况,第三种是使用线程并发库中的线程池创建一个线程).这两种方法都需要重写Run方法,具体的线程逻辑 ...
- Java多线程与并发库高级应用-java5线程并发库
java5 中的线程并发库 主要在java.util.concurrent包中 还有 java.util.concurrent.atomic子包和java.util.concurrent.lock子包 ...
- java并发库_并发库知识点整理
并发库(java.util.concurrent)中的工具数不胜数,那么我们梳理一下线程并发库中重要的一些常用工具: 1.
- 线程高级应用-心得8-java5线程并发库中同步集合Collections工具类的应用及案例分析
1. HashSet与HashMap的联系与区别? 区别:前者是单列后者是双列,就是hashmap有键有值,hashset只有键: 联系:HashSet的底层就是HashMap,可以参考HashSe ...
随机推荐
- Android NFC技术(三)——初次开发Android NFC你须知道NdefMessage和NdefRecord
Android NFC技术(三)--初次开发Android NFC你须知道NdefMessage和NdefRecord 这最近也是有好多天没写博客了,除了到处张罗着搬家之外,依旧还是许许多多的琐事阻碍 ...
- web报表工具FineReport常用函数的用法总结(文本函数)
文本函数 CHAR CHAR(number):根据指定数字返回对应的字符.CHAR函数可将计算机其他类型的数字代码转换为字符. Number:用于指定字符的数字,介于1Number:用于指定字符的数字 ...
- SharePoint 2013配置开发环境,需安装VS2012插件
SharePoint 2013已经安装好了,接下来就是配置开发环境,安装VS2012,但是,装好了以后,发现没有SharePoint 2013开发的支持,如下图: 然后,去网上查找资料,VS2012对 ...
- 负载均衡之让nginx跑起来
一个简单的原因,我不得不考虑负载 小源做了个网站,很简单,传统的java开放框架,和一个tomcat搞定,让人没想到的是网站既然火起来了,很快一个tomcat就搞不定了,怎么办? 网站访问量很大,既然 ...
- sqlite 数据类型 <转>
一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断.SQLite具有以下五种数据类型: 1.NULL:空值.2.INTEGER:带符号的整型,具体取决有存入数字 ...
- Thread.yield和join方法
参考:http://blog.csdn.net/dabing69221/article/details/17426953 一. Thread.yield( )方法: 使当前线程从执行状态(运行状态)变 ...
- JeeSite
JeeSite是一个 开源的企业信息管理系统 基础框架.主要定位于"企业信息管理"领域,可用作企业信息管理类系统.网站后台管理类系统等.JeeSite是非常强调开发的高效性.健壮性 ...
- 我如何踏上IT路
第一次开技术博客,第一篇博文就聊聊自己是如何走上IT这条路的.一直听人说"搞IT的"颇含贬低色彩,也有IT前辈奉劝不要轻易踏上这条路,但最终我这个本是化学化工专业的门外汉还是义无反 ...
- Storm 提交多个流例程
1.拓扑(Topology): builder.setBolt(TRANSFORM_BOLT, new TransformationBolt(), 1).shuffleGrouping(MY_SPOU ...
- memocache工作原理
1 Memcache是什么 Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的 ...