Java多線程進階(十八)—— J.U.C之synchronizer框架:CountDownLatch

1.jpg

本文首發於一世流雲的專欄: https://segmentfault.com/blog...

1、CountDownLatch簡介

CountDownLatch是一個輔助同步器類,用來做計數使用,它的做用有點相似於生活中的倒數計數器,先設定一個計數初始值,當計數降到0時,將會觸發一些事件,如火箭的倒數計時。segmentfault

初始計數值在構造CountDownLatch對象時傳入,每調用一次 countDown() 方法,計數值就會減1。多線程

線程能夠調用CountDownLatch的await方法進入阻塞,當計數值降到0時,全部以前調用await阻塞的線程都會釋放。框架

注意:CountDownLatch的初始計數值一旦降到0,沒法重置。若是須要重置,能夠考慮使用CyclicBarrier。

2、CountDownLatch使用示例

ContDownLatch通常有如下幾種用法:this

一、做爲一個開關/入口

將初始計數值爲1的 CountDownLatch 做爲一個的開關或入口:
在調用 countDown() 的線程打開入口前,全部調用 await 的線程都一直在入口處等待。spa

public class Driver {
    private static final int N = 10;
 
    public static void main() throws InterruptedException {
        CountDownLatch switcher = new CountDownLatch(1);
 
        for (int i = 0; i < N; ++i) {
            new Thread(new Worker(switcher)).start();
        }
 
        doSomething();
        switcher.countDown();       // 主線程開啓開關
 
    }
 
    public static void doSomething() {
    }
}
 
class Worker implements Runnable {
    private final CountDownLatch startSignal;
 
    Worker(CountDownLatch startSignal) {
        this.startSignal = startSignal;
    }
 
    public void run() {
        try {
            startSignal.await();    //全部執行線程在此處等待開關開啓
            doWork();
        } catch (InterruptedException ex) {
        }
    }
    void doWork() { ...}
}

二、做爲一個完成信號

將初始計數值爲N的 CountDownLatch做爲一個完成信號點:使某個線程在其它N個線程完成某項操做以前一直等待。線程

public class Driver {
    private static final int N = 10;
 
    public static void main() throws InterruptedException {
        CountDownLatch compsignal = new CountDownLatch(N);
 
        for (int i = 0; i < N; ++i) {
            new Thread(new Worker(compsignal)).start();
        }
 
        compsignal.await();       // 主線程等待其它N個線程完成
        doSomething();
    }
 
    public static void doSomething() {
    }
}
 
class Worker implements Runnable {
    private final CountDownLatch compSignal;
 
    Worker(CountDownLatch compSignal) {
        this.compSignal = compSignal;
    }
 
    public void run() {
        try {
            doWork();
            compSignal.countDown(); //每一個線程作完本身的事情後,就將計數器減去1
        } catch (InterruptedException ex) {
        }
    }
 
    void doWork() { ...}
}

3、CountDownLatch類/接口聲明

類聲明:
clipboard.pngcode

構造器:
clipboard.png對象

接口:
clipboard.pngblog

4、CountDownLatch原理

關於CountDownLatch的內部實現原理,讀者能夠參考:
Java多線程進階(九)—— J.U.C之locks框架:AQS共享功能剖析(4)接口

相關文章
相關標籤/搜索