java多线程-CounCountDownLatchh

java多线程-CountDownLatchh和CyclicBarrier

一、CountDownLatch

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

1、使用场景

1、开始执行前等待n 个线程完成各自的任务:例如应用程序启动类要确保在处理用户请求前,所有n个任务已经启动和运行了
2、死锁检测

2、方法
//构造方法
CountDownLatch latch = new CountDownLatch(int num);
//减少计数器
latch.countDown();

//主线程执行
latch.await();
3、如何使用
  • 开始执行主线程
  • 为N个线程创建CountDownLatch
  • N个线程开始执行
  • 主线程在latch处执行等待
  • 主线程开始执行
4、代码实例
package java_lang_Object;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Created by luckyboy on 2018/7/10.
 */

abstract class BaseHealthChecker implements Runnable{
    private CountDownLatch latch;
    private String service_Name;
    private boolean serviceUp;
    public BaseHealthChecker(String service_Name,CountDownLatch latch){
        this.latch = latch;
        this.service_Name = service_Name;

    }
    @Override
    public void run(){
        try{
            //验证类是否启动
            verifyService();
            //启动服务置为true
            serviceUp = true;
        }catch (Throwable t){
            t.printStackTrace();
            //启动失败则值为false
            serviceUp = false;
        }finally{
            if(latch != null){
                latch.countDown();
            }
        }
    }

    public abstract void verifyService();

    public String getServiceName() {
        return this.service_Name;
    }
    public boolean isServiceUp(){
        return this.serviceUp;
    }
}
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(3000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(this.getServiceName()+"is Up");
    }
}
class CacheHealthChecker extends BaseHealthChecker{
    public CacheHealthChecker(CountDownLatch latch){
        super("Cache Service",latch);
    }

    @Override
    public void verifyService() {
        System.out.println("Checking"+this.getServiceName());
        try{
            Thread.sleep(3000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(this.getServiceName()+"is Up");
    }
}

工具类,只有当我们的NetworkHealthChecker、DataBaseHealthChecker、CacheHealthChecker三个类启动了以后,最终才会执行判断是否所有的类输出一个true

class ApplicationStartupUtil{
    private static List<BaseHealthChecker> services;

    private static CountDownLatch latch;

    private ApplicationStartupUtil(){

    }
    private final static ApplicationStartupUtil INSTANCE = new ApplicationStartupUtil();

    public static ApplicationStartupUtil getInstance(){
        return INSTANCE;
    }

    public static void checkExternalServices(){
        boolean flag = true;
        latch = new CountDownLatch(3);
        services = new ArrayList<BaseHealthChecker>();
        services.add(new NetworkHealthChecker(latch));
        services.add(new DataBaseHealthChecker(latch));
        services.add(new CacheHealthChecker(latch));
        Executor executorService = Executors.newFixedThreadPool(services.size());
        for(final BaseHealthChecker v:services){
            executorService.execute(v);
        }
        try {
            latch.await();
            for(final BaseHealthChecker v:services){
                if(!v.isServiceUp()){
                    flag = false;
                }
            }
            System.out.println("External services validation completed !! Result was::"+flag);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

测试类

public class CountDownLatchTest_II {
    public static void main(String[] args){
        ApplicationStartupUtil application = ApplicationStartupUtil.getInstance();
        application.checkExternalServices();

    }

}

输出结果

CheckingNetwork Service
CheckingDatabase Service
CheckingCache Service
Database Serviceis Up
Cache Serviceis Up
Network Serviceis Up
External services validation completed !! Result was::true
总结:
  • 主线程必须在启动其他线程后立即调用CountDownLatch.await()方法,这样主喜线程就会在这个方法上阻塞,知道其他线程完成各自的任务
  • 其他的N个线程必须要引用主线程中创建的CountDownLatch对象,因为他们需要调用CountDownLatch.countDown()方法来告知主线程自己完成了任务
  • 每个线程执行了countDown()之后,我们的在CountDownLatch(int num)的num就会减1。知道num 减少到零,此时主线程就可以执行任务了

参考文章

https://howtodoinjava.com/core-java/multi-threading/threadpoolexecutor-callable-future-example/
http://www.importnew.com/15731.html
https://blog.csdn.net/zzg1229059735/article/details/61191679

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值