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

    技术2023-12-14  64

        学一个类,或者一个方法,先从它的字面意思理解起,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    **************班长最后关门走人

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

    Processed: 0.010, SQL: 9