CountDownLatch实现多线程等待后共同执行
01 CountDownLatch
CountDownLatch 通过 count 计数实现屏障设定(阻塞),当满足设定的条件后一个或者多个线程时候一起执行。这里的屏障指的就是一个线程会被阻塞,不再继续向下执行。
CountDownLatch 中的计数器会做减法。当执行到它的 await()方法之后,如果计数器不为 0,则阻塞,知道其他线程调用 countDown()之后扣减计数为 0 之后,原本阻塞的线程才会继续向下执行。
02 缺点
计数不能被重置。这就导致实现过程中不能动态的修改计数,只能按照设定好的计数来使用。
03 常用方法
await() 阻塞并等待计数为0再往下执行。
await(long timeout, TimeUnit unit) 阻塞并等待指定的时间,如果在指定的时间内计数未能到 0,则自动唤醒,向下执行。
countDown() 计数器中的计数减一
getCount() 获得当前计数的值
04 案例
Game.java
package com.page.concurrent.countdownlatch; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; public class Game { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(1); ArrayList<Runner> runners = new ArrayList<>(); for (int i = 0; i < 3; i++) { Runner runner = new Runner(countDownLatch); runner.start(); runners.add(runner); } System.out.println("ready?"); countDownLatch.await(); System.out.println("Go!"); } }
Runner.java
package com.page.concurrent.countdownlatch; import java.util.concurrent.CountDownLatch; public class Runner extends Thread { private final CountDownLatch countDownLatch; public Runner(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } @Override public void run() { try { Thread.sleep(1000 * 5); } catch (InterruptedException e) { System.out.println("Error " + e.getMessage()); } System.out.println(Thread.currentThread().getName() + " had ready! Waiting other runners."); countDownLatch.countDown(); System.out.println(Thread.currentThread().getName() + " GO!"); } }