Java多線程詳解(六)--CountDownLatch

一、說明

1.CountDownLatch是在java1.5被引入,跟它一起被引入的工具類還有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。
2.存在于java.util.cucurrent并發(fā)包下

二、原理

1.countDownLatch這個類使一個線程等待其他線程各自執(zhí)行完畢后再執(zhí)行。
2.是通過一個計數(shù)器來實現(xiàn)的,計數(shù)器的初始值是線程的數(shù)量。每當(dāng)一個線程執(zhí)行完畢后,計數(shù)器的值就-1,當(dāng)計數(shù)器的值為0時,表示所有線程都執(zhí)行完畢,然后在閉鎖上等待的線程就可以恢復(fù)工作了。

三、源碼

//構(gòu)造器
public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }

//調(diào)用await()方法的線程會被掛起,它會等待直到count值為0才繼續(xù)執(zhí)行
public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

//和await()類似,只不過等待一定的時間后count值還沒變?yōu)?的話就會繼續(xù)執(zhí)行
public boolean await(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

//將count值減1
public void countDown() {
        sync.releaseShared(1);
    }

//獲取count值
public long getCount() {
        return sync.getCount();
    }

三、測試

public class CountDownLatchTest {
    public static void main(String[] args) {
        System.out.println("主線程開始執(zhí)行~~~~~~");
        CountDownLatch latch = new CountDownLatch(2);
        ExecutorService ex_1 = Executors.newSingleThreadExecutor();
        ex_1.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("子線程1開始執(zhí)行:" + Thread.currentThread().getName());
                    Thread.sleep(3000);
                }catch (Exception e){
                    e.printStackTrace();
                }

                latch.countDown();
            }
        });

        ex_1.shutdown();
        ExecutorService ex_2 = Executors.newSingleThreadExecutor();
        ex_2.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("子線程2開始執(zhí)行:" + Thread.currentThread().getName());
                    Thread.sleep(3000);
                }catch (Exception e){
                    e.printStackTrace();
                }

                latch.countDown();
            }
        });

        ex_2.shutdown();
        System.out.println("等待兩個子線程執(zhí)行完畢~~~~~~~");
        System.out.println("latch start:" + latch.getCount());
        try {
            latch.await();
            System.out.println("latch end:" + latch.getCount());
        }catch (Exception e){
            e.printStackTrace();
        }

        System.out.println("主線程等待子線程執(zhí)行完畢,繼續(xù)執(zhí)行主線程");
    }
}

執(zhí)行結(jié)果:

主線程開始執(zhí)行~~~~~~
子線程1開始執(zhí)行:pool-1-thread-1
子線程2開始執(zhí)行:pool-2-thread-1
等待兩個子線程執(zhí)行完畢~~~~~~~
latch start:2
latch end:0
主線程等待子線程執(zhí)行完畢,繼續(xù)執(zhí)行主線程

四、模擬并發(fā)

public class CountDownLatchTest {
    public static void main(String[] args) {
        System.out.println("starting main~~~~~~" + Thread.currentThread().getName());
        CountDownLatch countDownLatch = new CountDownLatch(100);
        ExecutorService pool = Executors.newCachedThreadPool();
        for(int i =0; i< 100; i++){
            CountRunable runable = new CountRunable(countDownLatch);
            pool.execute(runable);
        }

        System.out.println("ending main~~~~~~"+ Thread.currentThread().getName());
    }


}

class CountRunable implements Runnable{
    private CountDownLatch downLatch;
    public CountRunable(CountDownLatch downLatch){
        this.downLatch = downLatch;
    }

    @Override
    public void run() {
        try {
            synchronized (downLatch){
                downLatch.countDown();
                System.out.println("thread counts = " + (downLatch.getCount()));
            }


            downLatch.await();
            System.out.println("concurrency counts = " + (100 - downLatch.getCount()));

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

執(zhí)行結(jié)果:

starting main~~~~~~main
thread counts = 99
thread counts = 98
thread counts = 97
thread counts = 96
thread counts = 95
thread counts = 94
thread counts = 93
thread counts = 92
thread counts = 91
thread counts = 90
thread counts = 89
thread counts = 88
thread counts = 87
thread counts = 86
thread counts = 85
thread counts = 84
thread counts = 83
thread counts = 82
thread counts = 81
thread counts = 80
thread counts = 79
thread counts = 78
thread counts = 77
thread counts = 76
thread counts = 75
thread counts = 74
thread counts = 73
thread counts = 72
thread counts = 71
thread counts = 70
thread counts = 69
thread counts = 68
thread counts = 67
thread counts = 66
thread counts = 65
thread counts = 64
thread counts = 63
thread counts = 62
thread counts = 61
thread counts = 60
thread counts = 59
thread counts = 58
thread counts = 57
thread counts = 56
thread counts = 55
thread counts = 54
thread counts = 53
thread counts = 52
thread counts = 51
thread counts = 50
thread counts = 49
thread counts = 48
thread counts = 47
thread counts = 46
thread counts = 45
thread counts = 44
thread counts = 43
thread counts = 42
thread counts = 41
thread counts = 40
thread counts = 39
thread counts = 38
thread counts = 37
thread counts = 36
thread counts = 35
thread counts = 34
thread counts = 33
thread counts = 32
thread counts = 31
thread counts = 30
thread counts = 29
thread counts = 28
thread counts = 27
thread counts = 26
thread counts = 25
thread counts = 24
thread counts = 23
thread counts = 22
thread counts = 21
thread counts = 20
thread counts = 19
thread counts = 18
thread counts = 17
thread counts = 16
thread counts = 15
thread counts = 14
thread counts = 13
thread counts = 12
thread counts = 11
thread counts = 10
thread counts = 9
thread counts = 8
thread counts = 7
thread counts = 6
thread counts = 5
thread counts = 4
thread counts = 3
thread counts = 2
thread counts = 1
ending main~~~~~~main
thread counts = 0
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100
concurrency counts = 100

五、結(jié)束語
countDownLatch是一個計數(shù)器,線程完成一個記錄一個,計數(shù)器遞減,只能只用一次

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容