Java多线程10:CountDownLatch组件的详细介绍——学习方腾飞Java并发编程的艺术

CountDownLatch

CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行后续工作

CountDownLatch是在java1.5被引入的,一起被引入的还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,这几个后面也会挨个介绍一下,它们都存在于java.util.concurrent包下。

CountDownLatch是通过一个计数器来实现的,计数器的初始值为设置的线程的数量,每当一个线程完成了自己的任务后,即执行countdown()方法之后,计数器的值就会减1,当计数器值到达0时,表示所有的线程已经完成了任务,然后在闭锁上等待的线程(await()方法)就可以恢复执行任务。

CountDownLatch例子

import java.util.concurrent.CountDownLatch;

/**
 * @author fitz.bai
 */
public class MyThread13 {
    private static CountDownLatch countDownLatch;

    public static void main(String[] args) {
        countDownLatch = new CountDownLatch(3);
        Thread aThread = new Thread(new MyThread13.waitRunner(countDownLatch), "awaitThread-a");
        Thread bThread = new Thread(new MyThread13.waitRunner(countDownLatch), "awaitThread-b");
        aThread.start();
        bThread.start();
        Thread cThread = new Thread(new MyThread13.downRunner(countDownLatch), "downThread-c");
        Thread dThread = new Thread(new MyThread13.downRunner(countDownLatch), "downThread-d");
        Thread eThread = new Thread(new MyThread13.downRunner(countDownLatch), "downThread-e");
        cThread.start();
        dThread.start();
        eThread.start();
    }

    static class waitRunner implements Runnable {
        private CountDownLatch countDownLatch;

        public waitRunner(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + "开始等待, 时间为" + System.currentTimeMillis());
                countDownLatch.await();
                System.out.println(Thread.currentThread().getName() + "结束等待, 时间为" + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class downRunner implements Runnable {
        private CountDownLatch countDownLatch;

        public downRunner(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + "开始执行, 时间为" + System.currentTimeMillis());
                Thread.sleep(1000);
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName() + "执行结束, 时间为" + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//执行结果
awaitThread-a开始等待, 时间为1533558652570
awaitThread-b开始等待, 时间为1533558652573
downThread-d开始执行, 时间为1533558652575
downThread-c开始执行, 时间为1533558652575
downThread-e开始执行, 时间为1533558652576
downThread-d执行结束, 时间为1533558653654
downThread-e执行结束, 时间为1533558653654
downThread-c执行结束, 时间为1533558653654
awaitThread-a结束等待, 时间为1533558653654
awaitThread-b结束等待, 时间为1533558653654

结论

执行结果看出:a、b两个线程等待cde三个线程执行完毕之后,几乎在同一时间同时执行a、b的await()之后的内容
CountDownLatch相当于是一种进化版本的等待/通知机制,它可以的实现的是多个工作线程完成任务后通知多个等待线程开始工作,例如上面3个线程完成之后通知另外两个线程开始工作。

CountDownLatch总结

CountDownLatch是通过“共享锁”实现的。在创建CountDownLatch中时,会传递一个int类型参数count,count是“锁计数器”的初始值,表示该“共享锁”最多能被多少个线程同时获取。当某线程调用该CountDownLatch对象的await()方法时,该线程会开始等待直到count个其他线程执行完countdown()方法,每当一个线程调用该CountDownLatch对象的countDown()方法时,将“锁计数器”-1,即count的值-1当“锁计数器”为0(count为0时),前面提到的等待线程继续运行后续的代码!

你可能感兴趣的:(Java并发艺术)