首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 並發同步工具類實戰:CountDownLatch、CyclicBarrier、Semaphore、BlockingQueue

     編輯:Java 程式設計入門

同步工具類分類與核心作用

封裝狀態,協調線程控制流:決定線程「等待」還是「繼續」。

工具核心隱喻典型場景關鍵方法
CountDownLatch倒計時閂鎖主線程等待多個初始化任務完成countDown(), await()
CyclicBarrier循環柵欄多線程分階段計算,階段間同步await()
Semaphore信號量/許可證資源池限流 (連接池、線程池)acquire(), release()
BlockingQueue阻塞隊列生產者-消費者、任務緩衝put(), take()

1. CountDownLatch:一等多,不可重用


// 主線程等待 10 個子任務完成
CountDownLatch latch = new CountDownLatch(10);
ExecutorService es = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
    es.execute(() -> {
        doWork();      // 耗時操作
        latch.countDown(); // 計數 -1
    });
}
latch.await(); // 阻塞直到計數歸零
System.out.println("All tasks done");
// 輸出順序:所有子任務 running → 依次 finished → 主線程 continue

特點:計數器只能遞減一次,不可重置。FutureTask 也可作為閉鎖 (get() 等待完成)。

2. Semaphore:控制並發訪問量


// 模擬 3 個數據庫連接,10 個線程競爭
Semaphore sem = new Semaphore(3); // 3 個許可證
for (int i = 0; i < 10; i++) new Thread(() -> {
    sem.acquire();           // 獲取許可,無則阻塞
    useConnection();         // 業務邏輯
    sem.release();           // 歸還許可
}).start();
// 輸出:同時只有 3 個線程在 useConnection,其餘阻塞等待

公平性:構造函數 new Semaphore(permits, true) 開啟公平模式 (FIFO),性能稍低。

3. CyclicBarrier:大家齊聚再出發,可重用


// 5 線程分階段任務,每階段需全部到達才能進入下一階段
CyclicBarrier barrier = new CyclicBarrier(5, () -> 
    System.out.println("所有線程到達柵欄,執行匯總邏輯..."));

for (int i = 0; i < 5; i++) new Thread(() -> {
    phase1(); 
    barrier.await(); // 阻塞等待
    phase2(); 
    barrier.await();
    phase3();
}).start();
// 輸出:各線程 phase1 不同步 → 到達 await 阻塞 → 最後一個到達觸發 barrierAction → 所有線程同時繼續 phase2

區別:Latch 計數歸零一次性;Barrier 到達方數可循環重用,且可選「柵欄動作」。

4. BlockingQueue:生產者-消費者基石


// 有界隊列,生產者慢消費者快 → 消費者阻塞;生產者快消費者慢 → 生產者阻塞
BlockingQueue queue = new LinkedBlockingQueue<>(100);

// 生產者
new Thread(() -> {
    while (true) {
        String item = produce();
        queue.put(item); // 滿則阻塞
    }
}).start();

// 6 個消費者
for (int i = 0; i < 6; i++) new Thread(() -> {
    while (true) {
        String item = queue.take(); // 空則阻塞
        consume(item);
    }
}).start();
// 輸出:每秒生產 1 個,6 消費者輪流消費,天然負載均衡

選型決策樹

  1. 需要等待一組事件完成一次性觸發 → CountDownLatch。
  2. 需要多線程分步驟同步,步驟間相互等待 → CyclicBarrier。
  3. 需要限制同時訪問資源的線程數 → Semaphore。
  4. 需要線程間傳遞數據/任務,天然阻塞平衡 → BlockingQueue。

進階提示

  • 所有工具類均基於 AbstractQueuedSynchronizer (AQS) 實現,理解 AQS 狀態變更與節點排隊機制,可洞悉底層原理。
  • Phaser (Java 7+) 結合了 Latch 和 Barrier 功能,支持動態註冊/註銷參與者,更靈活。
  • CompletableFuture 提供了更高級的組合式異步編排能力 (thenCompose, allOf, anyOf),現代並發首選。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved