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

Java 線程通訊機制詳解:synchronized、輪詢與 wait/notify 核心模式

     編輯:Java 相關知識

線程通訊的本質

多線程協作需解決:「線程間如何傳遞信號/數據」與「如何協調執行順序」。Java 提供三種層層遞進的機制。

1. synchronized 同步鎖(共享內存模式)

多線程持有同一物件鎖,透過鎖的互斥性實現隱式通訊:

public class MyObject {
    synchronized public void methodA() { /*...*/ }
    synchronized public void methodB() { /*...*/ }
}
// ThreadA 呼叫 methodA(), ThreadB 呼叫 methodB()
// 同一物件鎖下,B 必須等 A 釋放鎖才能執行

本質:共享變量 + 鎖同步。簡單但靈活性低,難以表達複雜協作條件。

2. while 輪詢(主動檢查模式)

線程 B 不斷迴圈檢查條件(如 list.size() == 5),條件滿足則行動:

while (true) {
    if (list.size() == 5) { /* 行動 */ break; }
}

缺點:佔用 CPU 空轉(「忙等待」),浪費資源;響應有延遲。

3. wait/notify 機制(標準協作模式)

Object 基礎方法,配合 synchronized 使用:

  • wait():釋放鎖,進入等待集合,阻塞直到被喚醒或超時。
  • notify():喚醒一個等待線程,重新競爭鎖。
  • notifyAll():喚醒所有等待線程。

經典生產者-消費者範例

// 共享鎖物件
Object lock = new Object();

// 消費者線程
synchronized (lock) {
    while (list.size() != 5) { // 必須用 while 防止虛假喚醒
        lock.wait(); // 釋放鎖、阻塞
    }
    // 條件滿足,繼續執行
}

// 生產者線程
synchronized (lock) {
    for (int i = 0; i < 10; i++) {
        list.add("elem");
        if (list.size() == 5) lock.notify(); // 通知消費者
        Thread.sleep(1000);
    }
}

關鍵注意事項

  1. 必須在 synchronized 區塊內呼叫wait/notify,否則拋 IllegalMonitorStateException。
  2. 用 while 而非 if 檢查條件,防止虛假喚醒。
  3. 通知過早問題:若 notify() 先於 wait() 執行,信號丟失,wait() 永久阻塞。解決:引入狀態標誌或改用 Condition / CountDownLatch 等高階工具。

現代替代方案

JDK 1.5+ java.util.concurrent 提供更強大工具:

  • BlockingQueue:生產消費首選,內建阻塞與同步。
  • CountDownLatch、CyclicBarrier、Phaser:協調多線程階段。
  • Lock + Condition:可支援多條件隊列、可中斷鎖。
  • CompletableFuture、Parallel Streams:聲明式併發。

總結

理解 wait/notify 底層機制有助於排查併發 Bug,但實戰中優先使用 JUC 高階組件,減少低層次同步錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved