[Java并發(fā)編程實(shí)戰(zhàn)] 閉鎖 CountDownLatch 實(shí)現(xiàn)(含代碼)

路漫漫其修遠(yuǎn)兮,吾將上下而求索?!峨x騷》

閉鎖

閉鎖(latch)是一種 Synchronizer,他可以延遲線程的進(jìn)度直到線程到達(dá)終止?fàn)顟B(tài)。

一個閉鎖工作起來就像一道大門:直到閉鎖達(dá)到終點(diǎn)狀態(tài)之前,門一直是關(guān)閉的,沒有線程通過,在終點(diǎn)狀態(tài)到來的時(shí)候,門開了,允許所有線程都通過。一旦閉鎖到達(dá)了終點(diǎn)狀態(tài),他就不能夠在改變狀態(tài)了,所以它會永遠(yuǎn)保持敞開的狀態(tài)。

閉鎖的應(yīng)用

  • 確保一個計(jì)算不會執(zhí)行,直到它需要的資源被初始化。
  • 確保一個服務(wù)不會開始,直到它依賴的服務(wù)都已經(jīng)開始。
  • 等待直到活動的所有部分都為繼續(xù)處理做好準(zhǔn)備。比如王者榮耀需要等待所有玩家準(zhǔn)備才能開始。

閉鎖的實(shí)現(xiàn)

CountDownLatch 是一個靈活的閉鎖實(shí)現(xiàn),可以用于上述幾種情況,允許一個或者多個線程等待一個事件集的發(fā)生。閉鎖的狀態(tài)包括一個計(jì)數(shù)器,初始為一個正數(shù),表示要等待的事件數(shù)。countDown方法對于計(jì)數(shù)器做減數(shù)操作,表示一個事件已經(jīng)發(fā)生了,而 await阻塞方法將阻塞當(dāng)前線程直到計(jì)數(shù)器減到零。

CountDownLatch示例

下面舉個例子,CountDownLatchTest 創(chuàng)建兩個特閉鎖對象。第一個是主線程用于判斷所有線程啟動完畢的閉鎖,用于阻塞子線程執(zhí)行直到所有線程都啟動完畢。第二個是子線程執(zhí)行完畢的閉鎖,直到每個線程都執(zhí)行完畢后,才統(tǒng)計(jì)總共運(yùn)行了多少時(shí)間。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest{
    
    private static CountDownLatch main_cdl = new CountDownLatch(1);//閉鎖1
    private static CountDownLatch sub_cdl = new CountDownLatch(5);//閉鎖2
    
    public static void main(String[] args) {
        //創(chuàng)建五個線程并啟動
        for(int i = 0; i < 5; i++) {
            new Thread(new SubThread()).start();
        }
        
        long start = System.nanoTime();
        main_cdl.countDown();//打開閉鎖,讓五個線程繼續(xù)執(zhí)行
        try {
            sub_cdl.await();//阻塞閉鎖,等待五個線程都執(zhí)行完畢
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long end = System.nanoTime();
        System.out.println(end - start);//五個線程總共執(zhí)行了多長時(shí)間
    }
    //子線程
    static class SubThread implements Runnable{
        public SubThread() {}
        @Override
        public void run() {
            try {
                main_cdl.await();//阻塞,等待主線程啟動所有子線程你
                System.out.println(Thread.currentThread().getName() + ":runing");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                sub_cdl.countDown();//子線程執(zhí)行完畢,計(jì)數(shù)器減1
            }
        }
    }
}

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


這里寫圖片描述

本文到此結(jié)束,我們已經(jīng)直到如何去使用閉鎖,和它使用的場景啦。

希望對你有幫助,歡迎關(guān)注我!謝謝~

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

相關(guān)閱讀更多精彩內(nèi)容

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