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("所有站点检查完毕,可以正常进行发车!!!!!!!!!"); } } } |
程序运行结果: 北京调度站正在进行车辆自检.......... 山东调度站正在进行车辆自检.......... 陕西调度站正在进行车辆自检.......... 山东调度站车辆自检完毕,一切正常 北京调度站车辆自检完毕,一切正常 陕西调度站车辆自检完毕,一切正常 所有站点检查完毕,可以正常进行发车!!!!!!!!! |