CountDownLatch使用
分享牛原创,CountDownLatch类的使用,CountDownLatch是一个工具类,运行主线程开启子线程的时候,子线程还没有结束的时候,主线程可以一直等待,直到初始化的现成的计数器count为0,主线程就可以不用等待继续执行了。count只能在实例化CountDownLatch类的时候初始化,没有其他的办法count注入值。
下面看一下,这样三个完成之后,计数器时1,则程序就是一直等待状态。永远不会向下执行。
countDown方法,当前线程调用此方法,则计数在实例化CountDownLatch中传入的值基础上减一。
awaint方法,调用此方法会一直阻塞当前线程,不会向下执行,直到计时器的值为0的时候程序才会继续向下执行。
1.1.2. 测试
下面的程序开始测试CountDownLatch的使用。
package com.shareniu.zkTest;
import java.util.concurrent.CountDownLatch;
public class ShareniuDriver {
private static final int N = 2;
public static void main(String[] args) throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
{
new Thread(new Worker(doneSignal,i)).start();
}
doneSignal.await();
doSomethingElse(); // don't let run yet
}
private static void doSomethingElse() {
System.out.println("分享牛 我在做其他事情.....");
}
static class Worker implements Runnable {
private CountDownLatch doneSignal;
private int i;
public Worker( CountDownLatch doneSignal,int i) {
this.doneSignal = doneSignal;
this.i=i;
}
public void run() {
try {
doWork();
} catch (Exception e) {
} finally {
doneSignal.countDown();
}
}
private void doWork() {
System.out.println("开始工作....."+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
上面的程序可以得出一个结论:count为0的时候,await()之后的方法才会去执行,否则一直处于等待状态。
上面的是启动2个线程,当我们把N设置为3的时候,也就是大于2的任意数的时候,启动2个线程,其他地方不变化,发现程序一直等待,不执行。这个也间接说明了,只有count为0的时候,程序才会继续走下去。
1.1.3. 工作原理
工作原理如下图所示:
1.1.4. 使用场景
程序启动的时候,根据业务开启几个线程去执行检查服务是否正常,主线程一直等待,当检查的线程都结束的时候,主线程才能去判断对应的所有的线程返回结果,检查是否正常。
比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。
具体的程序如下:
1.1.4.1. BaseHealthChecker 类,所有类的基类
package com.shareniu.zkTest;
import java.util.concurrent.CountDownLatch;
public abstract class BaseHealthChecker implements Runnable {
private CountDownLatch latch;
private String serviceName;
private boolean serviceUp;
public BaseHealthChecker(CountDownLatch latch, String serviceName) {
this.latch = latch;
this.serviceName = serviceName;
}
public void run() {
try {
verifyService();
serviceUp = true;
} catch (Exception e) {
e.printStackTrace(System.err);
serviceUp = false;
}finally{
if(latch != null) {
latch.countDown();
}
}
}
public abstract void verifyService();
public CountDownLatch getLatch() {
return latch;
}
public String getServiceName() {
return serviceName;
}
public boolean isServiceUp() {
return serviceUp;
}
}
1.1.4.2. NetworkHealthChecker 类
package com.shareniu.zkTest;
import java.util.concurrent.CountDownLatch;
public class NetworkHealthChecker extends BaseHealthChecker {
public NetworkHealthChecker(CountDownLatch latch, String serviceName) {
super(latch, serviceName);
}
@Override
public void verifyService() {
System.out.println("开始检查 " + this.getServiceName());
try
{
Thread.sleep(7000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(this.getServiceName() + " 检查结束");
}
}
1.1.4.3. CacheHealthChecker 类
package com.shareniu.zkTest;
import java.util.concurrent.CountDownLatch;
public class CacheHealthChecker extends BaseHealthChecker {
public CacheHealthChecker(CountDownLatch latch, String serviceName) {
super(latch, serviceName);
}
@Override
public void verifyService() {
System.out.println("开始检查 CacheHealthChecker" + this.getServiceName());
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(this.getServiceName() + "CacheHealthChecker 检查结束 ");
}
}
1.1.4.4. 测试类
package com.shareniu.zkTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AppTest {
private static List<BaseHealthChecker> services;
private static CountDownLatch latch;
public static void main(String[] args) throws InterruptedException {
latch = new CountDownLatch(2);
services=new ArrayList<BaseHealthChecker>();
services.add(new CacheHealthChecker(latch, "CacheHealthChecker"));
services.add(new NetworkHealthChecker(latch, "NetworkHealthChecker"));
ExecutorService executor = Executors.newFixedThreadPool(services.size());
for(final BaseHealthChecker v : services)
{
executor.execute(v);
}
//等待 指导所有的线程执行完毕
latch.await();
for(final BaseHealthChecker v : services)
{
boolean serviceUp = v.isServiceUp();
System.out.println(v.getServiceName()+":"+serviceUp);
}
}
}
运行结果如下所示:
开始检查 CacheHealthCheckerCacheHealthChecker
开始检查 NetworkHealthChecker
CacheHealthCheckerCacheHealthChecker 检查结束
NetworkHealthChecker 检查结束
CacheHealthChecker:true
NetworkHealthChecker:true
CountDownLatch使用的更多相关文章
- 多线程条件通行工具——CountDownLatch
CountDownLatch的作用是,线程进入等待后,需要计数器达到0才能通行. CountDownLatch(int)构造方法,指定初始计数. await()等待计数减至0. await(long, ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 同步辅助类CountDownLatch用法
CountDownLatch是一个同步辅助类,犹如倒计时计数器,创建对象时通过构造方法设置初始值,调用CountDownLatch对象的await()方法则使当前线程处于等待状态,调用countDow ...
- 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch
java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...
- Java并发之CountDownLatch
CountDownLatch是Java concurrent包下的一个同步工具.它可以让一个(或多个)线程等待,直到其他线程中的某些操作完成. 本质上是一个信号量,我们把它比作一个有N个插销的大门,它 ...
- Java多线程之CountDownLatch学习
给出官网上的例子:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html Java中conc ...
- 【Java】JDK类 CountDownLatch
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown() 方法,所以在当前计数到达 ...
- 【JUC】JDK1.8源码分析之CountDownLatch(五)
一.前言 分析完了CyclicBarrier后,下面分析CountDownLatch,CountDownLatch用于同步一个或多个任务,强制他们等待由其他任务执行的一组操作完成.CountDownL ...
- java多线程等待协调工作:CountDownLatch类的高级应用
一:说明 基本上对于线程初步了解的人,都是使用synchronized来同步线程的,也确实,它也是可以满足一些常用的问题.那么我们来说一些它不能解决的问题(其实是不怎么好解决的问题,并不是真的不能解决 ...
- 【JAVA并发编程实战】4、CountDownLatch
这是一个计数锁,说白了,就是当你上锁的时候,只有计数减少到0的时候,才会释放锁 package cn.xf.cp.ch05; public class TaskRunable implements R ...
随机推荐
- JavaScript树(一) 简介
树的相关术语 一个树结构包含一系列存在父子关系的节点. 每个节点都有一个父节点 (除了顶部的第一个节点)以及零个或多个子节点: 位于树顶部的节点叫作根节点(11) .它没有父节点.树中的每个元素都叫作 ...
- 【分享】几篇关于Repository 相关的讨论、提问、文章
一.引入 最近在了解DDD,对于里面Repository 有点疑问和关注.闲来无事,去找了一些文章,来补补.在这里分享出来给大家.文章大多数都是英文的,见谅哈. 二.推荐列表 2.1 Filters ...
- [HNOI 2001]软件开发
Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...
- ●HDU 1695 GCD
题链: http://acm.hdu.edu.cn/showproblem.php?pid=1695 题解: 容斥. 莫比乌斯反演,入门题. 问题化简:求满足x∈(1~n)和y∈(1~m),且gcd( ...
- 【网络流】【BZOJ1221】【HNOI2001】软件开发
原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1221 题意:你有3种方法进行对毛巾的处理,不同的处理方法有不同的cost,问你要如何规划才 ...
- ●BZOJ 3894 文理分科
题链: https://vijos.org/d/ljt12138/p/58c696b8d3d8a16c62a248d4 (要权限号啊...用这个交吧) 题解: 题目大意: N*M的矩阵,每个位置 ...
- bzoj3038上帝造题的七分钟2
3038: 上帝造题的七分钟2 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1679 Solved: 713[Submit][Status][Dis ...
- TDMA over WiFi
0 引言 TDMA可以修正WiFi中DCF机制中连接速率不同终端间信道占用时间片公平性缺陷,从而提升整体WiFi网络的性能.著名的UBNT的网桥就用其独创的TDMA技术为其赢得了市场.以前是不同的公司 ...
- SpringBoot多环境部署,在启动时动态设置相应的配置文件
项目中,往往在测试环境和正式环境拥有不同的配置,例如数据库连接,第三方库的appkey等.这时候,我们就要在不同的环境启用不同的配置 下面新建三个文件,分别表示开发环境,生产环境和测试环境的配置文件 ...
- make cmake gcc 间的关系
看了一些关于make cmake gcc间关系的帖子,其中这一篇简单明了. 作者:辉常哥链接:https://www.zhihu.com/question/36609459/answer/89743 ...