thread_CountDownLatch同步计数器
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同步计数器的更多相关文章
- 同步计数器 CountDownLatch
CountDownLatch 是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行. CountDownLatch 是通过一个计数器来实现的,计数器的初始值为线程的数量.每 ...
- CANopen学习——同步
在发送和接收之间必须相互协调和同步,为此,CANopen引入同步的概念. 同步报文:包含一个数据字节或者不含数据字节的CAN报文.数据字节中包含一个从1开始递增计数的同步计数器.溢出值可在参数(索引1 ...
- 04-时序逻辑电路设计之计数器——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的:以计数器为例学会简单的时序逻辑电路设计 实验平台:芯航线FPGA核心板 实验原理: 时序逻辑电路是指电路任何时刻的稳态输出不仅取决于当前的输入,还与前一时刻输入 ...
- Java 并发同步器之CountDownLatch、CyclicBarrier
一.简介 1.CountDownLatch是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞 ...
- 并发是个什么鬼之同步工具类CountDownLatch
扯淡 写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过.就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气.以至于大家会 ...
- 同步机制之--java之CountDownLatch闭锁
CountDownLatch闭锁 1.类介绍 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数初始化 CountDownLatch.CountDown ...
- 高级java必会系列一:多线程的简单使用
众所周知,开启线程2种方法:第一是实现Runable接口,第二继承Thread类.(当然内部类也算...)常用的,这里就不再赘述.本章主要分析总结线程池和常用调度类. 一.线程池 1.newCache ...
- Sharepoint 2010 工作流启动时处理出错
在Sharepoint 2010 中使用Sharepoint 2010 designer做了一个工作流: 运行工作流时,当主办工程师是“张三”的时候,工作流一启动就报错. -------------- ...
- TTL和CMOS
reprint from:http://blog.csdn.net/hemeinvyiqiluoben/article/details/9253249 TTL和COMS电平匹配以及电平转换的方法 一. ...
随机推荐
- E-R图样例
基本知识 基本的ER模型包含三类元素:实体.关系.属性. 实体(Entities):实体是首要的数据对象,常用于表示一个人.地方.某样事物或某个事件.一个特定的实体被称为实体实例(entity ins ...
- 【redis】2.redis可视化工具安装使用
redis可视化工具:Redis Desktop Manager 1.redis桌面管理工具[可视化工具]下载 下载地址:https://redisdesktop.com/download 2.点击安 ...
- 解决新浪微博API调用限制 突破rate_limit_status瓶颈
新浪微博开放平台API的调用和TWITTER接口一样,都是受限的,以小时为单位进行限定. 他有两个限制原则 1.用户不登录基于IP的限制,每小时1000次 2.用户登录了基于用户的限制,每小时1000 ...
- LaTeX:Figures, Tables, and Equations 插入图表和公式
Figures To insert a figure in a LaTeX document, you write lines like this: \begin{figure} \centering ...
- python读取大文件的方法及mmap内存映射模块
python计算文件的行数和读取某一行内容的实现方法 :最简单的办法是把文件读入一个大的列表中,然后统计列表的长度.如果文件的路径是以参数的形式filepath传递的,那么只用一行代码就可以完成我们的 ...
- C#程序输出信息到调试窗口的几种方式
网站项目: System.Diagnostics.Debug.WriteLine("aaa"); 控制项目:Console.WriteLine("bbb"); ...
- asset bundle打包策略
一次引用的 不单独打包 2次的看大小 小的不单独打包 2次以上单独打包 2这个值 可以测一测 取平衡
- LINUX 下编译不通过解答
在linux下编译android源码或者webkit等程序源码时,不论在源码下加什么错误,编译器都默认正确,检索不到错误,此时,可能是之前编译的生成文件默认编译器不再检索编译新修改过的文件,只是发现修 ...
- elastic不错的官方文档(中文)
https://www.blog-china.cn/template/documentHtml/1484101683485.html http://www.open-open.com/doc/list ...
- C#中如何动态加载DockPanel
在WinForm项目中要求实现动态加载DockPanel. 简单研究了下,演示代码如下: 很简单几行代码,实现了基本意图.看起来问题很快解决. 但是实际应用中发现几个问题: 1.当第一次运行时,doc ...