java 多執行緒CountDownLatch

业余砖家發表於2024-05-09

CountDownLatch 簡介

CountDownLatch 是 Java 中的一個同步工具類,可以用來確保一組執行緒等待其他執行緒完成各自工作後再繼續執行。

CountDownLatch 的應用場景

CountDownLatch 可以被廣泛應用於各種多執行緒協作的場景,例如:

  • 主執行緒等待多個子執行緒完成後再執行下一步操作。
  • 多個子任務並行執行,最後合併結果。
  • 平行計算中,等待所有計算任務完成後進行統一彙總。

CountDownLatch 的優缺點分析
優點
簡單易用:CountDownLatch 的使用非常簡單,透過 await 和 countDown 方法即可實現多執行緒的協作。
靈活性:可以根據具體場景指定等待的計數值,可以靈活控制多個執行緒的協作關係。
高效性:底層使用了 AQS(AbstractQueuedSynchronizer)來實現同步,能夠保證高效地協調多個執行緒的執行順序。
缺點
一次性:CountDownLatch 的計數值只能減少,無法重置。一旦計數值減至零,就不能再次使用。
無法中途取消:一旦等待開始,就無法中途取消等待,除非等待超時或者發生中斷。

CountDownLatch 的使用案例

以下是一個簡單的使用 CountDownLatch 的例子,假設有一個任務分配系統,其中有多個工人(執行緒)在處理任務,而一個管理者(主執行緒)需要等待所有工人完成他們的任務後才繼續執行。

import java.util.concurrent.CountDownLatch;
 
public class Main {
    public static void main(String[] args) throws InterruptedException {
        int workerCount = 5; // 假設有5個工人
        CountDownLatch latch = new CountDownLatch(workerCount);
 
        for (int i = 0; i < workerCount; i++) {
            Worker worker = new Worker(latch, "Worker " + i);
            Thread thread = new Thread(worker);
            thread.start();
        }
 
        latch.await(); // 等待所有工人完成任務
        System.out.println("所有工人任務完成,管理者繼續執行。");
    }
 
    static class Worker implements Runnable {
        private CountDownLatch latch;
        private String name;
 
        public Worker(CountDownLatch latch, String name) {
            this.latch = latch;
            this.name = name;
        }
 
        @Override
        public void run() {
            // 工人執行任務
            doWork();
            latch.countDown(); // 工人完成任務,計數減一
        }
 
        private void doWork() {
            System.out.println(name + " 開始工作。");
            try {
                Thread.sleep(1000); // 模擬工作耗時
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + " 工作完成。");
        }
    }
}

在這個例子中,我們建立了一個 CountDownLatch 例項,其計數器初始化為工人的數量(workerCount)。每個工人執行緒在開始後會立即執行它的任務,任務完成後會呼叫 countDown 方法。主執行緒在開始時呼叫 latch.await() 方法等待計數器變為0,即所有工人完成任務。當所有工人完成任務後,計數器變為0,await 方法返回,主執行緒繼續執行。

相關文章