天天看點

令仔學多線程系列(一)----同步工具類CountDownLatch

簡單介紹

    簡單的介紹下CountDownLatch,是在jdk1.5被引入的,是在

java.util.concurrent

包下,它允許一個或者多個線程一直等待,直到其他線程的操作執行完後再執行。

    CountDownLatch是通過一個計數器來實作的,計數器的初始值為線程的數量,下面代碼中的

count

就是初始時設定的線程數量。也就是閉鎖需要等待的線程數量。這個值隻能被設定一次,而且CountDownLatch沒有提供任何機制去重新設定這個計數值。

public CountDownLatch(int count) {...}           

    CountDownLatch在主線程啟動了設定的線程之後,需要立即調用CountDownLatch.await(),這樣主線程的操作就會在這個地方阻塞,知道設定的線程完成各自的任務。

public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }           

    有一點需要注意的就是,如果你給某一個東西上了鎖,那麼你怎麼着也得有開鎖的時候吧,CountDownLatch也可以當成一把鎖來看,是以再每執行完一個線程之後,你都要去開一下鎖,就是調用CountDownLatch.countDown()方法。

public void countDown() {
        sync.releaseShared(1);
    }           

    目的就是為了你上了10把鎖,每執行完一個任務就去解開一把鎖,要不然就會一直鎖着,線程就會一直阻塞在這個地方。countDown()方法就是開鎖的,每調用一次這個方法,count值就會減一,直到為0,主線程就能通過

await()

,回複執行自己的任務。

舉個應時的場景

    假如我是一個供貨的中間代理商,我從供貨商那裡拿到貨然後銷售給平台。所有供應商的貨物的報價在我這經過處理,每種物品選擇一個最低的報價顯示在平台上,薄利多銷嘛。

    如果平台來了一個search請求,我總不能一個供貨商一個供貨商的去查詢吧,查詢供應商的資料庫還需要時間的,而平台要求的search傳回時間肯定不希望太長。而且我最終還有把查到的價格做處理,這些都是時間,時間就是Money。

    怎麼辦?在這裡我可以應用CountDownLatch。

    上圖中有五個供貨商,就設定count數量為5,然後異步發送search請求消息,await一段時間(<平台要求的一次search傳回時間),然後把所有的價格統計再進行後期處理。

final CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i=0;i<5;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //調用不同的供應商
                    countDownLatch.countDown();   //每new 一個Thread記得要減一。
                }
            }).start();
        }
        try {
            countDownLatch.await(10000, TimeUnit.MILLISECONDS);   //等待10秒(<小于平台要求的傳回時間)
            //後續處理
        }catch (InterruptedException e){
            e.printStackTrace();
        }           

    先簡單的介紹到這裡,後期會對CountDownLatch再做深入的研究。