天天看點

閉鎖CountDownLatch的用法

現在有十個線程各自輸出0-50000中的所有偶數,假設我們試圖使用下面這段代碼計算整個程式的執行時間:

package concurrent;

class LatchDemo implements Runnable {

    @Override
    public void run() {
        for (int i = ; i <= ; i++)
            System.out.println(i);
    }

}

public class TestCountDownLatch {

    public static void main(String[] args) {

        LatchDemo ld = new LatchDemo();

        long start = System.currentTimeMillis();

        for (int i = ; i < ; i++)
            new Thread(ld).start();

        long end = System.currentTimeMillis();

        System.out.println("total time is " + (end - start));

    }

}
           

  會發現無法達到預期的效果,甚至在輸出的最後一行根本看不到“total time is XXX”的結果,這是正常的,因為在這個多線程的環境下,或許當其他線程還沒有将偶數完全輸出,main線程已經将時間計算完畢并且輸出了。要解決這個問題,我們需要使main線程中計算時間的代碼在其他所有線程運算全部完成之後才執行,這就是CountDownLatch的功能,下面我們使用CountDownLatch來改程序式:

package concurrent;

import java.util.concurrent.CountDownLatch;

class LatchDemo implements Runnable {

    private CountDownLatch latch;

    public LatchDemo(CountDownLatch latch) {
        this.latch = latch;
    }

    @Override
    public void run() {
        try {
            for (int i = ; i < ; i++)
                System.out.println(i);
        } finally {
            //使用finally確定倒計時操作一定可以執行
            latch.countDown();
        }
    }

}

public class TestCountDownLatch {

    public static void main(String[] args) {

        //參數5對應要等待的線程數量,我們在下面建立了5個線程
        CountDownLatch latch = new CountDownLatch();

        LatchDemo ld = new LatchDemo(latch);

        long start = System.currentTimeMillis();

        for (int i = ; i < ; i++)
            new Thread(ld).start();

        //等待其他所有線程的運算全部完成
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();

        System.out.println("total time is " + (end - start));

    }

}
           

  運作程式,發現可以正常計算整個程式的執行時間:

  

  

閉鎖CountDownLatch的用法

繼續閱讀