CountDownLatch知识点提要

381 阅读2分钟

CountDownLatch

概念

让一些线程阻塞直到另一些线程完成一系列操作才被唤醒

CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程就会被阻塞。其它线程调用CountDown方法会将计数器减1(调用CountDown方法的线程不会被阻塞),当计数器的值变成零时,因调用await方法被阻塞的线程会被唤醒,继续执行

场景

现在有这样一个场景,假设一个自习室里有7个人,其中有一个是班长,班长的主要职责就是在其它6个同学走了后,关灯,锁教室门,然后走人,因此班长是需要最后一个走的,那么有什么方法能够控制班长这个线程是最后一个执行,而其它线程是随机执行的

解决方案

这个时候就用到了CountDownLatch,计数器了。我们一共创建6个线程,然后计数器的值也设置成6

 // 计数器
 CountDownLatch countDownLatch = new CountDownLatch(6);

然后每次学生线程执行完,就让计数器的值减1

 for (int i = 0; i <= 6; i++) {
     new Thread(() -> {
         System.out.println(Thread.currentThread().getName() + "\t 上完自习,离开教室");
         countDownLatch.countDown();
     }, String.valueOf(i)).start();
 }

最后我们需要通过CountDownLatch的await方法来控制班长主线程的执行,这里 countDownLatch.await()可以想成是一道墙,只有当计数器的值为0的时候,墙才会消失,主线程才能继续往下执行

 countDownLatch.await();
 ​
 System.out.println(Thread.currentThread().getName() + "\t 班长最后关门");

不加CountDownLatch的执行结果,我们发现main线程提前已经执行完成了

 1  上完自习,离开教室
 0  上完自习,离开教室
 main   班长最后关门
 2  上完自习,离开教室
 3  上完自习,离开教室
 4  上完自习,离开教室
 5  上完自习,离开教室
 6  上完自习,离开教室

引入CountDownLatch后的执行结果,我们能够控制住main方法的执行,这样能够保证前提任务的执行

 0  上完自习,离开教室
 2  上完自习,离开教室
 4  上完自习,离开教室
 1  上完自习,离开教室
 5  上完自习,离开教室
 6  上完自习,离开教室
 3  上完自习,离开教室
 main   班长最后关门

完整代码

 package com.company;
 ​
 import java.util.concurrent.CountDownLatch;
 ​
 /**
  * @author shoukailiang
  * @version 1.0
  * @date 2021/8/7 17:53
  */
 class CountDownLatchDemo {
     public static void main(String[] args) throws InterruptedException {
         CountDownLatch countDownLatch = new CountDownLatch(6);
         for (int i = 0; i < 6; i++) {
             new Thread(()->{
                 System.out.println(Thread.currentThread().getName() + "\t 上完自习,离开教室");
                 countDownLatch.countDown();
             },String.valueOf(i)).start();
         }
         countDownLatch.await();
         System.out.println(Thread.currentThread().getName() + "\t 班长最后关门");
     }
 }
 ​