美文网首页javaandroid进阶
CountDownLatch的用法

CountDownLatch的用法

作者: JohnShen | 来源:发表于2016-03-02 17:53 被阅读4478次

    本文的示例参见JavaDoc API

    简介

    CountDownLatch是一个同步的辅助类,它可以允许一个或多个线程等待,直到一组在其它线程中的操作执行完成。

    一个CountDownLatch会通过一个给定的count数来被初始化。其中await()方法会一直阻塞,直到当前的count被减到0,而这个过程是通过调用countDown()方法来实现的。在await()方法不再阻塞以后,所有等待的线程都会被释放,并且任何await()的子调用都会立刻返回。这是一次性的--count不能被重置。如果你需要一种能重置count的版本,请考虑使用CyclicBarrier

    CountDownlatch是一个多功能的同步工具,可以被用于各种目的。一个CountDownLatch通过一个值为1的count被初始化,来作为一个开/关的门或门闩:所有调用了await()的线程都会在门前等待,直到门被一个线程通过调用countDown()打开。一个被初始化为N的CountDownLatch可以被用来“在N个线程都完成了某种操作(或者一些操作已经被完成了N次)之后创建一个线程”。

    CountDownLatch一个有用的属性就是它不需要线程们在继续执行之前,调用countDown来等待count被减到0。它简单地阻止了任何调用了await()的线程继续,直到所有的线程都能够通过。

    示例

    下面请看一个应用场景:
    有1个driver和5个worker,需要满足以下两点要求:

    • 当driver完成了全部的工作之后才允许worker们开始工作;
    • 当所有的worker都完成了自己的工作之后,driver主线程才能结束。
    public class Driver {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch startSignal = new CountDownLatch(1);
            CountDownLatch doneSignal = new CountDownLatch(5);
    
            // 依次创建并启动5个worker线程
            for (int i = 0; i < 5; ++i) {
                new Thread(new Worker(startSignal, doneSignal)).start();
            }
            
            System.out.println("Driver is doing something...");
            System.out.println("Driver is Finished, start all workers ...");
            startSignal.countDown(); // Driver执行完毕,发出开始信号,使所有的worker线程开始执行
            doneSignal.await(); // 等待所有的worker线程执行结束
            System.out.println("Finished.");
        }
    }
    
    class Worker implements Runnable{
        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;
        Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
        }
        public void run() {
            try {
                startSignal.await(); // 等待Driver线程执行完毕,获得开始信号
                System.out.println("Working now ...");
                doneSignal.countDown(); // 当前worker执行完毕,释放一个完成信号
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    运行结果:

    Driver is doing something...
    Driver is Finished, start all workers ...
    Working now ...
    Working now ...
    Working now ...
    Working now ...
    Working now ...
    Finished.
    

    相关文章

      网友评论

      本文标题:CountDownLatch的用法

      本文链接:https://www.haomeiwen.com/subject/vwenkttx.html