生產者-消費者模式是多線程編程中最基礎、最經典的協作模型。本文通過一個完整的示例,演示如何使用 wait()/notify()、synchronized 關鍵字實現線程間的數據同步與通信。
Thread.start() vs run():啟動新線程 vs 普通方法調用Thread.sleep():線程休眠,釋放 CPU 不釋放鎖synchronized:內置鎖,保證原子性與可見性wait()/notify():釋放鎖並進入等待隊列 / 喚醒等待線程,必須在 synchronized 塊中調用三個核心類協作:
count 變量及讀寫操作,內部使用 synchronized 保證線程安全。count,寫入後 notify() 喚醒消費者,隨後 wait() 釋放鎖等待下一輪。wait() 等待生產者通知,讀取 count 後 notify() 喚醒生產者。
package com.gloomyfish.jse.thirdteen;
public class ObjectData {
private int count = 0;
public synchronized void read() {
System.out.println("read count : " + count);
System.out.println();
}
public synchronized void write() {
count++;
System.out.println("write count : " + count);
}
}
package com.gloomyfish.jse.thirdteen;
public class ConsumerThread extends Thread {
private ObjectData data;
public ConsumerThread(ObjectData data) {
this.data = data;
}
@Override
public void run() {
while (true) {
try {
synchronized (data) {
data.wait(); // 釋放鎖,進入等待隊列
data.read(); // 讀取數據
data.notify(); // 喚醒生產者
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.gloomyfish.jse.thirdteen;
public class ProductThread extends Thread {
private ObjectData data;
public ProductThread(ObjectData data) {
this.data = data;
}
@Override
public void run() {
while (true) {
try {
synchronized (data) {
data.write(); // 寫入數據 (count++)
Thread.sleep(3000); // 模擬生產耗時
data.notify(); // 喚醒消費者
data.wait(); // 釋放鎖,等待消費者消費完畢
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MainTest {
public static void main(String[] args) {
ObjectData data = new ObjectData(); // 單一共享對象
new ConsumerThread(data).start(); // 啟動消費者
new ProductThread(data).start(); // 啟動生產者
}
}
ObjectData 實例,分別傳給生產者和消費者。write(),sleep(3s) 模擬耗時,調用 notify() 唤醒消費者,隨後 wait() 釋放鎖進入等待。read(),調用 notify() 唤醒生產者,循環回到 wait() 等待下一輪。ObjectData 這把「鎖」實現嚴格的輪流執行:生產→消費→生產→消費…notify() 後必須 wait(),否則會連續生產導致邏輯錯誤。data 對象作為鎖,保證互斥。while(condition) wait() 防禦。本例展示了 Java 基礎並發工具 (synchronized、wait/notify) 如何協作解決經典同步問題。實際開發中,更推薦使用 java.util.concurrent 包下的高級組件(如 BlockingQueue、Semaphore、Condition),代碼更簡潔、健壯且性能更優。