CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,
计数器大于0 时,await()方法会阻塞程序继续执行
 CountDownLatch如其所写,是一个倒计数的锁存器,当计数减至0时触发特定的事件。利用这种特性,可以让主线程等待子线程的结束。
1.一个模拟运动员比赛的例子 

class Player implements Runnable {
private int id;
private CountDownLatch begin;
private CountDownLatch end; public Player(int i, CountDownLatch begin, CountDownLatch end) {
super();
this.id = i;
this.begin = begin;
this.end = end;
} @Override
public void run() {
try {
begin.await(); // 等待begin的状态为0
Thread.sleep((long) (Math.random() * 100)); // 随机分配时间,即运动员完成时间
System.out.println("Play" + id + " arrived."); } catch (InterruptedException e) {
e.printStackTrace();
} finally {
end.countDown(); // 使end状态减1,最终减至0
}
}
}
public class CountDownLatchTest {
private static final int PLAYER_AMOUNT = 5; @Test
public void RaceTest1( ) {
// 对于每位运动员,CountDownLatch减1后即结束比赛
CountDownLatch begin = new CountDownLatch(1); // 对于整个比赛,所有运动员结束后才算结束
CountDownLatch end = new CountDownLatch(PLAYER_AMOUNT);
Player[] plays = new Player[PLAYER_AMOUNT]; for (int i = 0; i < PLAYER_AMOUNT; i++)
plays[i] = new Player(i + 1, begin, end); // 设置特定的线程池,大小为5
ExecutorService exe = Executors.newFixedThreadPool(PLAYER_AMOUNT);
for (Player p : plays){
exe.execute(p); // 分配线程
} System.out.println("Race begins!");
begin.countDown(); try {
end.await(); // 等待end状态变为0,即为比赛结束 } catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Race ends!");
}
exe.shutdown();
}
}

2.健康检查

public class CheckHealthStartup {
// List of service checkers
private static List<BaseHealthChecker> _services; // This latch will be used to wait on
private static CountDownLatch _latch; private CheckHealthStartup() {
} private final static CheckHealthStartup INSTANCE = new CheckHealthStartup(); public static CheckHealthStartup getInstance() {
return INSTANCE;
} public static boolean checkExternalServices() throws Exception {
// Initialize the latch with number of service checkers
_latch = new CountDownLatch(2);
_services = new ArrayList<BaseHealthChecker>();
// All add checker in lists _services.add(new NetworkHealthChecker(_latch));
_services.add(new DatabaseHealthChecker(_latch)); // Start service checkers using executor framework
Executor executor = Executors.newFixedThreadPool(_services.size()); for (final BaseHealthChecker v : _services) {
executor.execute(v);
} // Now wait till all services are checked
_latch.await(); // Services are file and now proceed startup
for (final BaseHealthChecker v : _services) {
if (!v.isServiceUp()) {
return false;
}
}
return true;
} public static void main(String[] args) {
boolean result = false;
try {
result = CheckHealthStartup.checkExternalServices();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("External services validation completed !! Result was :: " + result); }
} class NetworkHealthChecker extends BaseHealthChecker {
public NetworkHealthChecker(CountDownLatch latch) {
super("Network Service", latch);
} @Override
public void verifyService() {
System.out.println("Checking " + this.getServiceName());
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getServiceName() + " is UP");
}
} class DatabaseHealthChecker extends BaseHealthChecker {
public DatabaseHealthChecker(CountDownLatch latch) {
super("Database Service", latch);
} @Override
public void verifyService() {
System.out.println("Checking " + this.getServiceName());
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getServiceName() + " is UP");
}
} abstract class BaseHealthChecker implements Runnable { private CountDownLatch _latch;
private String _serviceName;
private boolean _serviceUp; // Get latch object in constructor so that after completing the task, thread
// can countDown() the latch
public BaseHealthChecker(String serviceName, CountDownLatch latch) {
super();
this._latch = latch;
this._serviceName = serviceName;
this._serviceUp = false;
} @Override
public void run() {
try {
verifyService();
_serviceUp = true;
} catch (Throwable t) {
t.printStackTrace(System.err);
_serviceUp = false;
} finally {
if (_latch != null) {
_latch.countDown();
}
}
} public String getServiceName() {
return _serviceName;
} public boolean isServiceUp() {
return _serviceUp;
} // This methos needs to be implemented by all specific service checker
public abstract void verifyService();
}

thread_CountDownLatch同步计数器的更多相关文章

  1. 同步计数器 CountDownLatch

    CountDownLatch 是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行. CountDownLatch 是通过一个计数器来实现的,计数器的初始值为线程的数量.每 ...

  2. CANopen学习——同步

    在发送和接收之间必须相互协调和同步,为此,CANopen引入同步的概念. 同步报文:包含一个数据字节或者不含数据字节的CAN报文.数据字节中包含一个从1开始递增计数的同步计数器.溢出值可在参数(索引1 ...

  3. 04-时序逻辑电路设计之计数器——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献 实验目的:以计数器为例学会简单的时序逻辑电路设计 实验平台:芯航线FPGA核心板 实验原理: 时序逻辑电路是指电路任何时刻的稳态输出不仅取决于当前的输入,还与前一时刻输入 ...

  4. Java 并发同步器之CountDownLatch、CyclicBarrier

    一.简介 1.CountDownLatch是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞 ...

  5. 并发是个什么鬼之同步工具类CountDownLatch

    扯淡 写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过.就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气.以至于大家会 ...

  6. 同步机制之--java之CountDownLatch闭锁

    CountDownLatch闭锁 1.类介绍 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数初始化 CountDownLatch.CountDown ...

  7. 高级java必会系列一:多线程的简单使用

    众所周知,开启线程2种方法:第一是实现Runable接口,第二继承Thread类.(当然内部类也算...)常用的,这里就不再赘述.本章主要分析总结线程池和常用调度类. 一.线程池 1.newCache ...

  8. Sharepoint 2010 工作流启动时处理出错

    在Sharepoint 2010 中使用Sharepoint 2010 designer做了一个工作流: 运行工作流时,当主办工程师是“张三”的时候,工作流一启动就报错. -------------- ...

  9. TTL和CMOS

    reprint from:http://blog.csdn.net/hemeinvyiqiluoben/article/details/9253249 TTL和COMS电平匹配以及电平转换的方法 一. ...

随机推荐

  1. Laravel简⃣单⃣的⃣路⃣由⃣

    在⃣routes.php文⃣件⃣中⃣写⃣如⃣下⃣几⃣个⃣函⃣数⃣: Route::get('/', function () { return view('welcome'); }); // 获⃣取⃣a ...

  2. fiddler在ios10.3系统抓包https失败原因解决

    一直是按照以往的设置抓包,设置代理ip,通过Safari下载安装证书,抓包https怎么显示证书无效呢?难道证书被apple设为黑名单了?google后发现,IOS10.3以后,安装了证书不是默认启用 ...

  3. C语言i++和++i的区别和指针*(a++)和*(++a)的区别

    i++ :先引用后增加++i :先增加后引用i++ :先在i所在的表达式中使用i的当前值,后让i加1 ++i :让i先加1,然后在i所在的表达式中使用i的新值 一.c语言中i++和++i的运行效果是不 ...

  4. Jupyter Notebook 快捷键

    Jupyter Notebook 快捷键 从命令模式进入编辑模式需按 Enter 键,从编辑模式切换到命令模式需按Esc 键. Jupyter Notebook 是一个交互式笔记本程序, 其有丰富的快 ...

  5. Chrome/FireFox处理JSON的插件

    Chrome/FireFox处理JSON的插件 JSON插件   效果对比 对于json的数据如果不编排一下格式查看起来很费劲,今天推荐一款chrome/Firfox下处理json的插件JSON-ha ...

  6. Druid对比Redshift

    Redshift 内部使用了亚马逊取得了授权的ParAccel 实时注入数据 抛开可能的性能不同, 有功能性的不同 Druid 适合分析大数据量的流式数据, 也能够实时加载和聚合数据一般来讲, 传统的 ...

  7. linux 的计划任务 cron

    https://serverfault.com/questions/587696/how-to-restart-php-fpm-from-cron 我也遇到了这个问题,想用cron 来启动php-fp ...

  8. 云计算之路-试用Azure:制作虚拟机自定义镜像

    虚拟机自定义镜像(Image)是一个很有用的功能,可以在一台虚拟机上配置好基本的系统环境,然后做个镜像,以后创建虚拟机直接从这个镜像创建,会省掉很多重复的配置工作. 阿里云与UCloud都有这个功能, ...

  9. android wifi调试(无线调试) 一步到位

    没有数据线时候,怎么进行调试开发?只要在一个局域网内,最好选择wifi调试! 网上有很多这样的教程,但是有很多步.很繁琐.最近我在gp上下载了一个软件可以实现点击一步就可以了.不需要在手机上输入任何命 ...

  10. ASUS主板ALC887声卡,RTL81XX网卡,黑苹果驱动安装

    折腾了一下午终于在黑苹果上成功的安装了网卡,声卡驱动: 我的配置: 主板 ASUS b75m-a 声卡 ALC887 网卡 RTL8168F 安装所需工具: MutiBest 下载OS对应的版本即可  ...