博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CountDownLatch学习
阅读量:5253 次
发布时间:2019-06-14

本文共 4293 字,大约阅读时间需要 14 分钟。

参考原文

CountDownLatch是什么

CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。

单词Latch的中文翻译是门闩,也就是有“门锁”的功能,所以当门没有打开时,N个人是不能进入屋内的,也就是N个线程是不能继续往下运行的,支持这样的特性可以控制线程执行任务的时机

CountDownLatch是通过一个计数器来实现的,计数器的初始化值为线程的数量。每当一个线程完成了自己的任务后,计数器的值会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务了。

CountDownLatch 常用API

构造方法:

public CountDown(int count){} //count初始化计数值,一旦count初始化完成后,就不可重新初始化或者修改CountDownLatch对象的内部计数器的值。

常用方法:

public void await() {}; //使当前线程挂起,直到计数值为0时,才继续往下执行。public boolean await(long timeout , TimeUnit timeUnit) throws InterruptExcetion {};public void  countDown() {} //将count值减1

应用场景

CountDownLatch的一个非常典型的应用场景就是:有一个任务想要往下执行,但必须等到其他多个任务执行(如果是单个任务 顺序执行就好了)完毕后才进行继续往下执行。此时,我们可以在这个等待其他任务的线程里调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。

import java.util.Arrays;import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.Executor;import java.util.concurrent.Executors;/** * 模拟程序启动时 相关环境检查 */public class CountDownLatchTest {    public static void main(String[] args) {        try {            Boolean result = ApplicationStartupUtil.checkExtenalServoce();            if(result) {                System.out.println("健康检查全部健康");            } else {                throw new RuntimeException("程序依赖环境不健康");            }        } catch (Exception e) {            e.printStackTrace();        }    }}abstract class BaseHealthChecker implements Runnable {    private CountDownLatch countDownLatch ;    protected boolean isHealth ;    private String serviceName ;    public BaseHealthChecker(String serviceName , CountDownLatch countDownLatch) {        this.countDownLatch = countDownLatch;        this.serviceName = serviceName ;        isHealth = false ;    }    @Override    public void run() {        try {            this.verifyService();            isHealth = true ;        }catch (Exception e) {            e.printStackTrace();            isHealth = false ;        } finally {            if(countDownLatch != null) {                countDownLatch.countDown();            }        }    }    abstract void verifyService() ;    public boolean isHealth() {        return isHealth;    }    public String getServiceName() {        return serviceName;    }}class NetWorkHealthChecker extends BaseHealthChecker {    public NetWorkHealthChecker( CountDownLatch countDownLatch) {        super( "NetWorkHealthChecker" , countDownLatch ) ;    }    @Override    void verifyService() {        System.out.println("starting Checking " + this.getServiceName());        try {            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println( this.getServiceName() + " is Health");        isHealth = true ;    }}class DatabaseHealthChecker extends BaseHealthChecker {    public DatabaseHealthChecker( CountDownLatch countDownLatch) {        super( "DatabaseHealthChecker" , countDownLatch ) ;    }    @Override    void verifyService() {        System.out.println("starting Checking " + this.getServiceName());        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println( this.getServiceName() + " is Health");        isHealth = true ;    }}class ApplicationStartupUtil {    private static List
healthCheckerList ; private static CountDownLatch countDownLatch ; private ApplicationStartupUtil() { } public static boolean checkExtenalServoce() throws Exception { countDownLatch = new CountDownLatch(2) ; healthCheckerList = Arrays.asList(new DatabaseHealthChecker(countDownLatch) , new NetWorkHealthChecker(countDownLatch)) ; Executor executor = Executors.newFixedThreadPool(healthCheckerList.size()) ; healthCheckerList.forEach((num)-> executor.execute(num)); countDownLatch.await() ; System.out.println(countDownLatch.getCount()); //等待健康检查完毕 healthCheckerList.forEach((num) -> { System.out.println(num.isHealth); if(!num.isHealth()) { throw new RuntimeException(num.getServiceName() + "健康检查失败"); } }); return true ; }}

转载于:https://www.cnblogs.com/boothsun/p/7168510.html

你可能感兴趣的文章
javascript基础:window对象内置对话框、模式和非模式对话框、传值方法
查看>>
springboot学习(一):创建项目
查看>>
选择器
查看>>
Google最新截屏案例详解
查看>>
文件对比与差异提取的实现
查看>>
修长城 (区间DP)
查看>>
android intent 传递list或者对象
查看>>
javascript面向对象精要第二章函数整理精要
查看>>
iOS开发——Xcode快捷键
查看>>
linux虚拟机CentOS 7完整安装流程截图
查看>>
AndroidManifest.xml文件详解(uses-feature)
查看>>
bzoj 1087 互不侵犯King
查看>>
(随笔)关于人生的一点新感悟
查看>>
JavaScript 随意记
查看>>
CodeForces 1103E. Radix sum
查看>>
Virtual PC2007 + Redhat9下的网络配置
查看>>
字体的术语
查看>>
每天一个linux命令(20):find命令之exec
查看>>
nagios 抓取数据插件ndoutils 学习
查看>>
date日期 格式化
查看>>