Java線程-閉鎖(CountDownLatch)

CountDownLatch有時被稱爲“閉鎖”,其作用相當於一扇門:在CountDownLatch達到結束狀態之前,這扇門一直是關閉的,並且沒有任何線程能通過,當到達結束狀態時,這扇門會打開並允許所有的線程通過。當CountDownLatch到達結束狀態後,將不會再改變狀態,因此這扇門將永遠保持打開狀態。CountDownLatch可以用來確保某些活動直到其它活動都完成後才繼續執行。
她與CyclicBarrier有什麼樣的區別呢?
(1)、CountDownLatch是不可重置的,因此無法重用;CyclicBarrier沒用這種限制,可以重用。
(2)、CountDownLatch的組合是countDown/await,無論是一個線程還是多個線程,只要countDown足夠的次數,才能繼續下一步,進行後面的任務,它是屬於事件驅動的;而CyclicBarrier使用了await,只有當所有的併發線程調用了await,完成所有的任務,才能繼續接下來的任務,CyclicBarrier側重的是線程,而不是事件。

用CountDownLatch實現排隊場景:
假設有10個人排隊,我們將其分成5個人一批,通過CountDownLatch來協調批次。

public class Thread_CountDownLatch {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(6);
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new FirstBatchWorker(latch));
            t.start();
        }
        for (int i= 0; i < 5; i++) {
            Thread t = new Thread(new SecondBatchWorker(latch));
            t.start();
        }
        // 注意:這裏是演示目的的邏輯,並不是推薦的協調方式
        while (latch.getCount() != 1) {
            Thread.sleep(100L);
        }
        System.out.println("Wait for first batch finish");
        latch.countDown();
    }
    static class FirstBatchWorker implements Runnable {
        private CountDownLatch latch;
        public FirstBatchWorker(CountDownLatch latch) {
            this.latch = latch;
        }
        @Override
        public void run() {
            System.out.println("First batch executed!");
            latch.countDown();
        }
    }
    static class SecondBatchWorker implements Runnable {
        private CountDownLatch latch;
        public SecondBatchWorker(CountDownLatch latch) {
            this.latch = latch;
        }
        @Override
        public void run() {
            try {
                latch.await();
                System.out.println("Second batch executed!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

CountDownLatch的調度方式相對簡單,後一批次的線程進行await,等待前一批countDown足夠多次。這個例子也從側面體現出了它的侷限性,雖然它也能夠支持10個人排隊的情況,但是因爲不能重用,如果要支持更多人排隊,就不能依賴一個CountDownLatch進行了,其編譯運行輸出如下:

First batch executed!
First batch executed!
First batch executed!
First batch executed!
First batch executed!
Wait for first batch finish
Second batch executed!
Second batch executed!
Second batch executed!
Second batch executed!
Second batch executed!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章