Java经常使用多线程辅助工具---countdownLatch

前言

        上一篇博文说到semaphore,一个增强版的synchronized,该多线程辅助工具适用于控制对资源操做或者访问的场景。如今有一张场景是,须要等各个线程都都执行完了再进行下一步的操做,好比须要批量对上传的文件进行压缩,上传十个文件,压缩成一个包,这时候,就须要等上传完十个之后再进行压缩操做,相似于阻塞,concurrent包提供了countdownLatch辅助工具。java

        countdownLatch,中文翻译是门闩的意思,相似一个计数器,控制线程执行任务的时机,以组团的方式一块儿执行任务。该类会判断count计数不为0时,则呈wait状态,也就是屏障处等待,若是为0则继续执行。多线程

入门

         开启两个线程进行计数,同时主线程在wait状态,最后实现组团执行后续任务:工具

@Test
    public void testCountDownLatch() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(2);
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                log.info("开始count,当前是线程:{},时间是:{}",Thread.currentThread().getName(),LocalDateTime.now());
                try {
                    Thread.currentThread().sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                latch.countDown();
            }).start();
        }

        log.info("等待计数器count,如今是:{}", LocalDateTime.now());
        latch.await();
        log.info("结束计数器count,如今是:{}", LocalDateTime.now());
    }

    运行结果是:spa

比较复杂的使用案例线程

 模拟运动员从到场准备到开跑的过程,具体代码以下:翻译

@Test
public void testCountDownLatch2() throws InterruptedException {
    CountDownLatch comingTag = new CountDownLatch(5);
    CountDownLatch waitTag = new CountDownLatch(1);
    CountDownLatch waitRunTag = new CountDownLatch(5);
    CountDownLatch beginTag = new CountDownLatch(1);
    CountDownLatch endTag = new CountDownLatch(5);

    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            try {
                Thread.sleep(5000);
                log.info("{}号运动员已经入场,time:{}", Thread.currentThread().getName(), LocalDateTime.now());
                comingTag.countDown();

                waitTag.await();

                log.info("{}号运动员开始准备,time:{}", Thread.currentThread().getName(), LocalDateTime.now());
                Thread.sleep(3000);
                waitRunTag.countDown();

                log.info("{}号运动员准备结束,time:{}", Thread.currentThread().getName(), LocalDateTime.now());
                beginTag.await();
                log.info("{}号运动员开跑,time:{}", Thread.currentThread().getName(), LocalDateTime.now());

                Thread.sleep(2000);
                log.info("{}号运动员跑完了,time:{}", Thread.currentThread().getName(), LocalDateTime.now());
                endTag.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    comingTag.await();
    log.info("运动员所有入场,time:{}", LocalDateTime.now());

    log.info("预备口令,time:{}", LocalDateTime.now());
    Thread.sleep(2000);
    waitTag.countDown();

    waitRunTag.await();
    log.info("远动员准备完毕,time:{}", LocalDateTime.now());

    log.info("发令枪响,time:{}", LocalDateTime.now());
    Thread.sleep(2000);
    beginTag.countDown();

    endTag.await();
    log.info("所有运动员到达终点,time:{}", LocalDateTime.now());
}

运行结果是:code

相关文章
相关标签/搜索