CountDownLatch 倒计数器,是多线程并发时使用的类。
主要有2个应用场景:协调子线程结束和子线程开始
场景1:协调子线程结束,等待所有子线程结束
countDown() 执行多次 -》 await() 执行一次
例如:组织4个人开会,所有人员都到齐就开始
public class CountDownLatchTest1 { public static void main(String[] args) throws InterruptedException { //倒计数4个 CountDownLatch countDownLatch = new CountDownLatch(4); Thread f1 = new Thread(()->{ countDownLatch.countDown(); System.out.println("f1 ok"); }); Thread f2 = new Thread(()->{ countDownLatch.countDown(); System.out.println("f2 ok"); }); Thread f3 = new Thread(()->{ countDownLatch.countDown(); System.out.println("f3 ok"); }); Thread f4 = new Thread(()->{ try { System.out.println("f4在上卫生间,马上到"); Thread.sleep(1500); System.out.println("f4上完卫生间了"); countDownLatch.countDown(); System.out.println("f4 ok"); } catch (InterruptedException e) { throw new RuntimeException(e); } }); f1.start(); f2.start(); f3.start(); f4.start(); System.out.println("所有人都通知了"); countDownLatch.await(); System.out.println("人员到齐开会"); } }
场景2:协调子线程开始,统一各线程的开始时机
await() 执行多次 -》countDown() 执行一次
例如:比赛时,发令枪响了,就开始
public class CountDownLatchTest2 { public static void main(String[] args) throws InterruptedException { //这里设置1个计数,所有线程等待这1个计数 CountDownLatch countDownLatch = new CountDownLatch(1); Thread f1 = new Thread(()->{ System.out.println("f1 等待"); waitToFight(countDownLatch); System.out.println("f1 出发"); }); Thread f2 = new Thread(()->{ System.out.println("f2 等待"); waitToFight(countDownLatch); System.out.println("f2 出发"); }); Thread f3 = new Thread(()->{ System.out.println("f3 等待"); waitToFight(countDownLatch); System.out.println("f3 出发"); }); Thread f4 = new Thread(()->{ System.out.println("f4 等待"); waitToFight(countDownLatch); System.out.println("f4 出发"); }); f1.start(); f2.start(); f3.start(); f4.start(); System.out.println("倒计时5秒"); Thread.sleep(5000); countDownLatch.countDown(); System.out.println("比赛开始"); } //调用countDownLatch等待 private static void waitToFight(CountDownLatch countDownLatch){ try { countDownLatch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } } }
核心方法:
方法 | 功能 |
---|---|
await() | 等待latch为0 |
await(long timeout, TimeUnit unit) | 等待latch为0,或者超时 |
countDown() | latch数减1 |
getCount() | 获取当前latch数 |