Java併發程式設計實戰--閉鎖 CountDownLatch

衣舞晨風發表於2017-05-24

閉鎖是一種同步工具類,可以延遲執行緒的進度直到其到達終止狀態。閉鎖的作用相當於一扇門:在閉鎖到達結束狀態之前,這扇門一直是關閉的,並且沒有任何執行緒能通過,當到達結束狀態時,這扇門會開啟並允許所有的執行緒通過。當閉鎖到達結束狀態後,將不會再改變狀態,因此這扇門將永遠保持開啟狀態。

閉鎖可以用來確保某些活動直到其他活動都完成後才繼續執行。

CountDownLatch是一種靈活的閉鎖實現,可以在上述各種情況中使用,它可以使一個或多個執行緒等待一組事件發生。閉鎖狀態包括一個計數器,該計數器被初始化為一個正數,表示需要等待的事件數量。countDown方法遞減計數器,表示有一個事件已經發生了,而await方法等待計數器達到零,這表示所有需要等待的事件都已經發生。如果計數器的值非零,那麼await會一直阻塞直到計數器為零,或者等待中的執行緒中斷,或者等待超時。

可以向CountDownLatch物件設定一個初始的數字作為計數值,任何呼叫這個物件上的await()方法都會阻塞,直到這個計數器的計數值被其他的執行緒減為0為止。

下面程式TestHarness中給出了閉鎖的兩種常見用法。TestHarness建立一定數量的執行緒,利用它們併發地執行指定的任務。它使用兩個閉鎖,分別表示“起始門”和“結束門”。起始門計數器的初始值為1,而結束門計數器的初始值為工作執行緒的數量。每個工作執行緒首先要做到就是在啟動門上等待,從而確保所有執行緒都就緒後才開始執行。而每個執行緒要做的最後一個事情是將呼叫結束門的countDown方法減1 ,這能使主執行緒高效低等待直到所有工作執行緒都執行完畢,因此可以統計所消耗的時間。

public class TestHarness {
    public long timeTasks(int nThreads, final Runnable task)
            throws InterruptedException {
        // 開始的倒數鎖
        final CountDownLatch startGate = new CountDownLatch(1);
        // 結束的倒數鎖
        final CountDownLatch endGate = new CountDownLatch(nThreads);

        for (int i = 0; i < nThreads; i++) {
            Thread t = new Thread() {
                public void run() {
                    try {
                        startGate.await();
                        try {
                            task.run();
                        } finally {
                            endGate.countDown();
                        }
                    } catch (InterruptedException ignored) {
                    }
                }
            };
            t.start();
        }

        long start = System.nanoTime();
        startGate.countDown();
        endGate.await();
        long end = System.nanoTime();
        return end - start;
    }
}

java併發程式設計實戰pdf及案例原始碼下載:
http://download.csdn.net/detail/xunzaosiyecao/9851028

作者:jiankunking 出處:http://blog.csdn.net/jiankunking

相關文章