Java面试之JUC系列:CountDownLatch
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() + " 上完自习,离开教室"); countDownLatch.countDown(); }, String.valueOf(i)).start(); }
最后我们需要通过CountDownLatch的await方法来控制班长主线程的执行,这里 countDownLatch.await()可以想成是一道墙,只有当计数器的值为0的时候,墙才会消失,主线程才能继续往下执行
countDownLatch.await(); System.out.println(Thread.currentThread().getName() + " 班长最后关门");
不加CountDownLatch的执行结果,我们发现main线程提前已经执行完成了
1 上完自习,离开教室 0 上完自习,离开教室 main 班长最后关门 2 上完自习,离开教室 3 上完自习,离开教室 4 上完自习,离开教室 5 上完自习,离开教室 6 上完自习,离开教室
引入CountDownLatch后的执行结果,我们能够控制住main方法的执行,这样能够保证前提任务的执行
0 上完自习,离开教室 2 上完自习,离开教室 4 上完自习,离开教室 1 上完自习,离开教室 5 上完自习,离开教室 6 上完自习,离开教室 3 上完自习,离开教室 main 班长最后关门
完整代码
package com.moxi.interview.study.thread; import java.util.concurrent.CountDownLatch; /** */ public 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() + " 上完自习,离开教室"); countDownLatch.countDown(); }, String.valueOf(i)).start(); } countDownLatch.await(); System.out.println(Thread.currentThread().getName() + " 班长最后关门"); } }
上一篇:
通过多线程提高代码的执行效率例子