CountDownLatch在java.util.concurrent.CountDownLatch包里面,他通常用在多线程中,假如说我们现在有一件事情开了多线程去完成,但是我们需要保证所有的线程都成功运行结束,再去执行后面的代码,这个时候CountDownLatch这个类就派上用场了。

我们可以把CountDownLatch传入到每个线程里面去,在线程执行成功时调用countDownLatch.countDown();方法,然后在主线程里面执行完多线程初始化和分发执行之后执行countDownLatch.await();这样,只有在每个线程执行成功以后,也就是CountDownLatch的计数器减到0以后,才会执行countDownLatch.await()后面的代码。

简单的应用场景是这样的,但是具体的怎么设计还是需要仔细斟酌,否则有可能会出现countDownLatch.countDown();永远无法减为0的情况。

 

下面一个简单的例子来实现这一应用场景:


package org.hzg.countDownLatch;

import java.util.concurrent.CountDownLatch;

/**
* Created by hzgal on 2019-3-5.
*/
public abstract class DangerCenter implements Runnable {
   private CountDownLatch countDownLatch;      //计数器
   private String station;                      //危险品调度站
   private boolean isOkToSentCar;              //检查结果,是否满足发车条件

   public DangerCenter(CountDownLatch countDownLatch,String stationName) {
       this.countDownLatch = countDownLatch;
       this.station = stationName;
       this.isOkToSentCar = false;
   }

   @Override
   public void run() {
       try {
           check();
           isOkToSentCar = true;
       }catch (Exception e) {
           e.printStackTrace();
           isOkToSentCar = false;
       }finally {
           if(countDownLatch != null) {
               countDownLatch.countDown();
           }
       }
   }

   /**
    * 定义抽象的check方法,用于实现了DangerCenter的各级调度中心来重写check方法,因为每个调度中心自检的方法可能不一样
    */
   public abstract void check();

   public CountDownLatch getCountDownLatch() {
       return countDownLatch;
   }

   public void setCountDownLatch(CountDownLatch countDownLatch) {
       this.countDownLatch = countDownLatch;
   }

   public String getStation() {
       return station;
   }

   public void setStation(String station) {
       this.station = station;
   }

   public boolean isOkToSentCar() {
       return isOkToSentCar;
   }

   public void setOkToSentCar(boolean okToSentCar) {
       isOkToSentCar = okToSentCar;
   }
}
package org.hzg.countDownLatch;

import java.util.concurrent.CountDownLatch;

/**
* Created by hzgal on 2019-3-5.
*/
public class BeijingStation extends DangerCenter {
   private static String stationName = "北京危险品调度站";

   public BeijingStation(CountDownLatch countDownLatch) {
       super(countDownLatch,stationName);
   }

   @Override
   public void check() {
       System.out.println("北京调度站正在进行车辆自检..........");

       try {
           Thread.sleep(2000);
       }catch (Exception e) {
           e.printStackTrace();
       }

       System.out.println("北京调度站车辆自检完毕,一切正常");
   }
}
package org.hzg.countDownLatch;

import java.util.concurrent.CountDownLatch;

/**
* Created by hzgal on 2019-3-5.
*/
public class ShandongStation extends DangerCenter {
   private static String stationName = "山东危险品调度站";

   public ShandongStation(CountDownLatch countDownLatch) {
       super(countDownLatch,stationName);
   }

   @Override
   public void check() {
       System.out.println("山东调度站正在进行车辆自检..........");

       try {
           Thread.sleep(1000);
       }catch (Exception e) {
           e.printStackTrace();
       }

       System.out.println("山东调度站车辆自检完毕,一切正常");
   }
}
package org.hzg.countDownLatch;

import java.util.concurrent.CountDownLatch;

/**
* Created by hzgal on 2019-3-5.
*/
public class ShanxiStation extends DangerCenter {
   private static String stationName = "陕西危险品调度站";

   public ShanxiStation(CountDownLatch countDownLatch) {
       super(countDownLatch,stationName);
   }

   @Override
   public void check() {
       System.out.println("陕西调度站正在进行车辆自检..........");

       try {
           Thread.sleep(3000);
       }catch (Exception e) {
           e.printStackTrace();
       }

       System.out.println("陕西调度站车辆自检完毕,一切正常");
   }
}
package org.hzg.countDownLatch;

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

/**
* Created by hzgal on 2019-3-5.
*/
public class Demo {
   public static void main(String[] args) {
       boolean isAllOk = true;

       List<DangerCenter> stationList = new ArrayList<DangerCenter>();
       CountDownLatch countDownLatch = new CountDownLatch(3);
       stationList.add(new BeijingStation(countDownLatch));
       stationList.add(new ShandongStation(countDownLatch));
       stationList.add(new ShanxiStation(countDownLatch));

       Executor stationThreadPool = Executors.newFixedThreadPool(3);

       for(DangerCenter stationCenter : stationList) {
           stationThreadPool.execute(stationCenter);
       }

       try {
           countDownLatch.await();
       }catch (Exception e) {
           e.printStackTrace();
       }

       for(DangerCenter stationCenter : stationList) {
           if(!stationCenter.isOkToSentCar()) {
               isAllOk = false;
           }
       }

       if (isAllOk) {
           System.out.println("所有站点检查完毕,可以正常进行发车!!!!!!!!!");
       }
   }
}
程序运行结果:

北京调度站正在进行车辆自检..........

山东调度站正在进行车辆自检..........

陕西调度站正在进行车辆自检..........

山东调度站车辆自检完毕,一切正常

北京调度站车辆自检完毕,一切正常

陕西调度站车辆自检完毕,一切正常

所有站点检查完毕,可以正常进行发车!!!!!!!!!