原来CountDownLatch是用于线程间的调度

    学一个类,或者一个方法,先从它的字面意思理解起,CountDownLatch,倒计时门闩,大家都看过发射火箭的最后阶段吧,10,9,8...0...发射,我们可以把它理解成倒计时发射器也可以,它是JUC包下的类,主要用于线程间调度的,接下来,我们想一个场景来理解下怎样使用CountDownLatch,在学校我们上晚自习,最后呢由班长负责,关灯,锁门,班长只能是等所有的同学都离开后,才能关灯锁门,我们先来看一个demo。

public class CountDownLatchDemo {

    public static void main(String[] args) throws Exception {


        for (int i = 1; i < 7; i++) {

            new Thread(() -> {

                System.err.println(Thread.currentThread().getName() + "\t上完自习,离开教室");
            }, "同学" + i).start();
        }

        System.err.println(Thread.currentThread().getName() + "\t**************班长最后关门走人");

    }

}

执行结果

同学1    上完自习,离开教室
同学6    上完自习,离开教室
main    **************班长最后关门走人
同学5    上完自习,离开教室
同学4    上完自习,离开教室
同学3    上完自习,离开教室
同学2    上完自习,离开教室

    这里呢,我们启动六个线程来模拟上晚自习的六位同学,主线程呢,模拟班长关门走人,从执行结果来看,显然主线程即班长没有等到大家都走后,就关门走人了,显示是会被揍的,那怎样解决这个问题呢,CountDownLatch就登场了,看下它的主要三个方法,

  • 构造方法,它只有一个构造函数,需要传入一个计数器

    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }

  • countDown方法,每执行一次,构造函数的计数器减一,当计数器的值变为0时,调用await方法被阻塞的线程会被唤醒
  • await方法,当一个或多个线程调用await方法时,调用线程会被阻塞,计数器到0后,该方法以后的代码才会执行

    我们继续拿上边的同学们上晚自习的例子来说,这里我们传入的计数器应该是6,就是上晚自习的六位同学,当每走一位同学呢,我们就调用一次countDown方法,也就是计数器减一,让主线调用await方法,直到countDown方法到0,await方法以后的代码才会继续执行,我们在来看一个demo。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {

    public static void main(String[] args) throws Exception {

        CountDownLatch cdl = new CountDownLatch(6);

        for (int i = 1; i < 7; i++) {

            new Thread(() -> {

                System.err.println(Thread.currentThread().getName() + "\t上完自习,离开教室");
                cdl.countDown();
            }, "同学" + i).start();
        }

        cdl.await();
        System.err.println(Thread.currentThread().getName() + "\t**************班长最后关门走人");

    }

}

执行结果

同学1    上完自习,离开教室
同学2    上完自习,离开教室
同学4    上完自习,离开教室
同学3    上完自习,离开教室
同学5    上完自习,离开教室
同学6    上完自习,离开教室
main    **************班长最后关门走人

    看执行结果,就符合正常的逻辑了,当同学们都离开教室后,班长才可以关门走人,解决了线程间调度的问题,好了,下篇见。

你可能感兴趣的:(java,CountDownLatch,java面试,java高级,JUC包下线程调度类)