七、併發工具類之CountDownLatch

CountDownLatch

一個線程需要等到其他線程進行某操作時,可以使用CountDownLatch。 CountDownLatch構造方法,帶有一個int類型的參數。

public CountDownLatch(int count) 

當一個線程調用countDownLatch.await()時,線程會等待。直到其他線程執行 countDownLatch.countDown()。每執行一個countDown方法,初始化的count會減一,直到count=0時,等待線程才被喚醒。

假設場景顧客餐廳吃飯,需要等待做飯,炒菜,上湯都完成了,纔開始吃飯。 代碼:

//顧客線程
public class Customer implements  Runnable {

    private final CountDownLatch countDownLatch;

    public Customer(CountDownLatch countDownLatch){
        this.countDownLatch=countDownLatch;
    }
    public void run() {
        System.out.println("點完菜,等待開吃");
        try {
            this.countDownLatch.await();
            System.out.println("開飯了。。。。。。。。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


}

public  static  void main(String[] args) throws InterruptedException {
        final CountDownLatch countDownLatch = new CountDownLatch(3);

        Thread customer = new Thread(new Customer(countDownLatch));
        //顧客進餐廳點菜
        customer.start();

        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("做飯");
                }finally {
                    countDownLatch.countDown();
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("炒菜");
                }finally {
                    countDownLatch.countDown();
                }
            }
        }.start();
        
        new Thread(){
            @Override
            public void run() {
                try {
                    System.out.println("上湯");
                }finally {
                    countDownLatch.countDown();
                }
            }
        }.start();

        customer.join();
    }

輸出:

點完菜,等待開吃
做飯
炒菜
上湯
開飯了。。。。。。。。

結果正確,等待做飯,炒菜,上湯都完成了,纔開始吃飯。

總結:

  1. countDownLatch內部通過共享鎖實現
  2. countDown方法最好放在finally代碼塊中執行,防止線程永遠等待
  3. CountDownLatch再 count減到0之後,再次執行countDown不會有影響,count不變。
  4. await方法有重載方法 public boolean await(long timeout, TimeUnit unit),等待一段時間後恢復。
  5. countDownLatch只能使用一次,count=0時,不能回滾再次使用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章