Java并发之CountDownLatch应用场景

2019 Java 开发者跳槽指南.pdf (吐血整理)….>>>


CountDownLatch是在Java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。本文主要讲CountDownLatch


官方是这样描述CountDownLatch

 A synchronization aid that allows one or more threads to wait until
 a set of operations being performed in other threads completes.

CountDownLatch是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。

原理

CountDownLatch是通过一个计数器来实现的,计数器的初始化值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已完成任务,然后在闭锁上等待的线程就可以恢复执行任务。

Java并发之CountDownLatch应用场景

(图片来自网络)


我们来一起看一下CoundDownLatch结构 JDK1.8

Java并发之CountDownLatch应用场景

CountDownLatch(int) : 初始化计数器

countDown() :计数器减1

getCount(): 获取当前计数器

await(): 线程会被挂起,它会等待直到计数器值为0才继续执行

await(long,TimeUnit):线程会被挂起某段时间后继续执行


应用场景

1.开始执行前等待n个线程完成各自任务: 例如table_A、table_B、table_A、table_D统计4个表数量,然后进行统计总数量。

2.实现最大的并行性:模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。


案例

主程序入口

       try {
            CountDownLatch latch = new CountDownLatch(4);
            for (int i = 1; i <= 4; i++) {
                new Thread(new MyThread(latch,i)).start(); //启用四个线程
            }
            latch.await(); //主线程执行完毕
            MyThread.sum(); //最后统计总数
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

线程实现类

    int threadNumber ;
   static int tab1 = 0,tab2 = 0,tab3 = 0,tab4 = 0;
    CountDownLatch countDownLatch;
    MyThread(CountDownLatch countDownLatch ,int threadName){
        this.countDownLatch = countDownLatch;
        this.threadNumber = threadName;
    }
    @Override
    public void run(){
        try{
            switch (threadNumber) {
                case 1: tab1 = new Random().nextInt(100);
                    System.out.println("当前线程" + Thread.currentThread().getName()  + ", 表1数量:" +tab1); 
                    break;
                case 2: tab2 = new Random().nextInt(100);
                    System.out.println("当前线程" + Thread.currentThread().getName()  + ", 表2数量:" +tab2);
                    break;
                case 3: tab3 = new Random().nextInt(100);
                    System.out.println("当前线程" + Thread.currentThread().getName()  + ", 表3数量:"+tab3);
                    break;
                case 4: tab4 = new Random().nextInt(100);
                    System.out.println("当前线程" + Thread.currentThread().getName()  + ", 表4数量:" + tab4);
                    break;
                default:
                    System.out.println("异常了");break;
            }
        }finally {
            if (countDownLatch != null) {
                countDownLatch.countDown();//避免阻塞  计数器减1
            }
        }
    }

    public static void sum(){
        System.out.print("总数据量=");
        System.out.println(tab1 + tab2 + tab3 +tab4);
    }

结果

当前线程Thread-0, 表1数量:5
当前线程Thread-2, 表3数量:60
当前线程Thread-1, 表2数量:48
当前线程Thread-3, 表4数量:22
总数据量=135

以上代码有不妥的地方,请指教

▼长按以下二维码即可关注▼

Java并发之CountDownLatch应用场景


原文始发于微信公众号(木子道):Java并发之CountDownLatch应用场景