JAVA多线程(十二)Java多线程之CountDownLatch

1.JAVA多线程(十二)Java多线程之CountDownLatch

1.1 CountDownLatch是什么?

CountDownLatch 是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

  1. 某一线程在开始运行前等待 n 个线程执行完毕。将 CountDownLatch 的计数器初始化为 n :new CountDownLatch(n),每当一个任务线程执行完毕,就将计数器减 1 countdownlatch.countDown(),当计数器的值变为 0 时,在CountDownLatch上 await() 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。

  2. 实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的 CountDownLatch 对象,将其计数器初始化为 1 :new CountDownLatch(1),多个线程在开始执行任务前首先 coundownlatch.await(),当主线程调用 countDown() 时,计数器变为 0,多个线程同时被唤醒。

  3. CountDownLatch维护了一个计数器 cnt,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那些因为调用 await() 方法而在等待的线程就会被唤醒。

在这里插入图片描述

1.2 CountdownLatch使用例子

package com.yuanxw.chapter12;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

public class CountdownLatchExample {
    /** 随机数:使用long参数的所有64位作为因子值。 **/
    private static Random random = new Random(System.currentTimeMillis());
    /** 总线程数 **/
    private static final int TOTAL_THREAD_NUMBER = 5;
    /** 通过线程池,创建5个线程 **/
    private static ExecutorService executorService = Executors.newFixedThreadPool(TOTAL_THREAD_NUMBER);
    /** 创建CountDownLatch对象 **/
    private static CountDownLatch countDownLatch = new CountDownLatch(TOTAL_THREAD_NUMBER);

    public static void main(String[] args) throws InterruptedException {
        IntStream.range(0,5).forEach(i->{
            executorService.execute(()->{
                doWorking();
                /** 将count值减1 **/
                countDownLatch.countDown();
            });
        });
        /** 当前线程等到锁存器计数到零  **/
        countDownLatch.await();
        executorService.shutdown();
        System.out.println("所有线程工作已经执行完成!!!");
    }

    /**
     * 模拟工作方法
     */
    private static void doWorking(){
        try {
            System.out.println(String.format("线程【%s】工作>>开始", Thread.currentThread().getName()));
            Thread.sleep(random.nextInt(1000));
            System.out.println(String.format("线程【%s】工作<<结束", Thread.currentThread().getName()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

执行结果:

线程【pool-1-thread-2】工作>>开始
线程【pool-1-thread-5】工作>>开始
线程【pool-1-thread-3】工作>>开始
线程【pool-1-thread-4】工作>>开始
线程【pool-1-thread-1】工作>>开始
线程【pool-1-thread-4】工作<<结束
线程【pool-1-thread-2】工作<<结束
线程【pool-1-thread-3】工作<<结束
线程【pool-1-thread-1】工作<<结束
线程【pool-1-thread-5】工作<<结束
所有线程工作已经执行完成!!!

– 以上为《JAVA多线程(十二)Java多线程之CountDownLatch》,如有不当之处请指出,我后续逐步完善更正,大家共同提高。谢谢大家对我的关注。

——厚积薄发(yuanxw)


版权声明:本文为yuan_xw原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。