CountDownLatch與CyclicBarrier

CountDownLatch

CountDownLatch這個類使一個線程等待其他線程完成各自的工作再執(zhí)行,例如主線程希望子線程完成操作后讓自線程使用。
CountDownLatch是通過計(jì)數(shù)器實(shí)現(xiàn),每次完成一個任務(wù)后,計(jì)數(shù)器減一當(dāng)為0時,CountDownLatch.await()方法的線程就可以恢復(fù)執(zhí)行任務(wù)。


圖片 5.png

如圖我們Tw1線程Tw2線程 執(zhí)行了await方法 進(jìn)行等待,這是countDownlotch設(shè)置為5,ta、tb、tc、td調(diào)用countDown方法讓計(jì)數(shù)器減一,當(dāng)計(jì)數(shù)器為0時,Tw1、Tw2線程恢復(fù)運(yùn)行。

注意:不是子countdownlatch不是線程的數(shù)量、而且當(dāng)countdownchlatch不等于線程數(shù)
public class UseCountDownLatch {

   static CountDownLatch latch = new CountDownLatch(4);

    private static class InitThread implements Runnable{

        public void run() {
            System.out.println("Thread_"+Thread.currentThread().getId()
                    +" ready init work......");
            latch.countDown();
          
        }
    }
    
  public static void main(String[] args) throws InterruptedException {
     
        new Thread(new BusiThread()).start();
        for(int i=0;i<=3;i++){
            Thread thread = new Thread(new InitThread());
            thread.start();
        }

        latch.await();
        System.out.println("Main do ites work........");
    }
}

demo中演示的是一段 開啟四個子線程,主線程調(diào)用await進(jìn)入阻塞狀態(tài),調(diào)用countDown方法,當(dāng)countdownchlatch為0時,主線程阻塞狀態(tài)恢復(fù)。

CyclicBarrier

CyclicBarrier是一種線程間的屏障,一組線程到達(dá)一個屏障(也可以叫同步點(diǎn))時被阻塞,直到最后一個線程到達(dá)屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續(xù)運(yùn)行。
CyclicBarrier默認(rèn)的構(gòu)造方法是CyclicBarrier(int parties),其參數(shù)表示屏障攔截的線程數(shù)量,每個線程調(diào)用await方法告訴CyclicBarrier我已經(jīng)到達(dá)了屏障,然后當(dāng)前線程被阻塞。
CyclicBarrier還提供一個更高級的構(gòu)造函數(shù)CyclicBarrier(int parties,Runnable barrierAction),用于在線程到達(dá)屏障時,優(yōu)先執(zhí)行barrierAction,方便處理更復(fù)雜的業(yè)務(wù)場景。

}S3V32`PS)TZFW%1SXYLGCF.png

public class UseCyclicBarrier {

    private static CyclicBarrier barrier
            = new CyclicBarrier(4,new CollectThread());


    public static void main(String[] args) {
        for(int i=0;i<4;i++){
            Thread thread = new Thread(new SubThread());
            thread.start();
        }

    }

    /*匯總的任務(wù)*/
    private static class CollectThread implements Runnable{

        @Override
        public void run() {
            System.out.println("do other business........");
        }
    }

    /*相互等待的子線程*/
    private static class SubThread implements Runnable{

        @Override
        public void run() {
            long id = Thread.currentThread().getId();
            resultMap.put(Thread.currentThread().getId()+"",id);
            try {
                Thread.sleep(1000+id);
                System.out.println("Thread_"+id+" ....do something ");
                barrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}

這里我們開啟了4個子線程,他們?nèi)客瓿晒ぷ骱?,匯總線程CollectThread執(zhí)行。

兩者區(qū)別

CountDownLatch的計(jì)數(shù)器只能使用一次,而CyclicBarrier的計(jì)數(shù)器可以反復(fù)使用。
CountDownLatch.await一般阻塞工作線程,所有的進(jìn)行預(yù)備工作的線程執(zhí)行countDown,而CyclicBarrier通過工作線程調(diào)用await從而自行阻塞,直到所有工作線程達(dá)到指定屏障,再大家一起往下走。
在控制多個線程同時運(yùn)行上,CountDownLatch可以不限線程數(shù)量,而CyclicBarrier是固定線程數(shù)。
同時,CyclicBarrier還可以提供一個barrierAction,合并多線程計(jì)算結(jié)果。

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

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

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