準確說應為「生產者-消費者-倉儲」三方協作。核心邏輯:
實現依賴 Object 的 wait()、notifyAll() 機制。
/**
* Java線程:並發協作-生產者消費者模型
* @author leizhimin
*/
public class Test {
public static void main(String[] args) {
Godown godown = new Godown(30); // 初始庫存30
// 3消費者,7生產者
new Consumer(50, godown).start();
new Consumer(20, godown).start();
new Consumer(30, godown).start();
new Producer(10, godown).start();
new Producer(10, godown).start();
new Producer(10, godown).start();
new Producer(10, godown).start();
new Producer(10, godown).start();
new Producer(10, godown).start();
new Producer(80, godown).start();
}
}
/** 倉庫:共享資源,內建同步協作邏輯 */
class Godown {
public static final int max_size = 100; // 最大容量
public int curnum; // 當前庫存
Godown() {}
Godown(int curnum) { this.curnum = curnum; }
/** 生產指定數量 */
public synchronized void produce(int neednum) {
while (neednum + curnum > max_size) { // 條件不滿足,等待
System.out.println("要生產的產品數量" + neednum + "超過剩余庫存量" + (max_size - curnum) + ",暫時不能執行生產任務!");
try { wait(); } catch (InterruptedException e) { e.printStackTrace(); }
}
curnum += neednum; // 執行生產
System.out.println("已經生產了" + neednum + "個產品,現倉儲量為" + curnum);
notifyAll(); // 喚醒所有等待者
}
/** 消費指定數量 */
public synchronized void consume(int neednum) {
while (curnum < neednum) { // 條件不滿足,等待
try { wait(); } catch (InterruptedException e) { e.printStackTrace(); }
}
curnum -= neednum; // 執行消費
System.out.println("已經消費了" + neednum + "個產品,現倉儲量為" + curnum);
notifyAll(); // 喚醒所有等待者
}
}
/** 生產者線程 */
class Producer extends Thread {
private int neednum; private Godown godown;
Producer(int neednum, Godown godown) { this.neednum = neednum; this.godown = godown; }
public void run() { godown.produce(neednum); }
}
/** 消費者線程 */
class Consumer extends Thread {
private int neednum; private Godown godown;
Consumer(int neednum, Godown godown) { this.neednum = neednum; this.godown = godown; }
public void run() { godown.consume(neednum); }
}
已經生產了10個產品,現倉儲量為40
已經生產了10個產品,現倉儲量為50
已經消費了50個產品,現倉儲量為0
已經生產了80個產品,現倉儲量為80
已經消費了30個產品,現倉儲量為50
已經生產了10個產品,現倉儲量為60
已經消費了20個產品,現倉儲量為40
已經生產了10個產品,現倉儲量為50
已經生產了10個產品,現倉儲量為60
已經生產了10個產品,現倉儲量為70
Process finished with exit code 0
流程解讀:
synchronized 方法鎖住 Godown 實例BlockingQueue 等高級併發組件替代手動 wait/notify