天天看點

java消費者生産者設計模式_設計模式-生産者與消費者Java實作

幽靈工作室提供

對于多線程程式來說,不管任何程式設計語言,生産者和消費者模型都是最經典的。就像學習每一門程式設計語言一樣,Hello World!都是最經典的例子。

實際上,準确說應該是“生産者-消費者-倉儲”模型,離開了倉儲,生産者消費者模型就顯得沒有說服力了。

對于此模型,應該明确一下幾點:

1、生産者僅僅在倉儲未滿時候生産,倉滿則停止生産。

2、消費者僅僅在倉儲有産品時候才能消費,倉空則等待。

3、當消費者發現倉儲沒産品可消費時候會通知生産者生産。

4、生産者在生産出可消費産品時候,應該通知等待的消費者去消費。

此模型将要結合java.lang.Object的wait與notify、notifyAll方法來實作以上的需求。這是非常重要的

package youling.studio.producerandconsumer;

public class Main {

public static void main(String[] args) throws InterruptedException {

Godown godown = new Godown(1000, 40);

new Thread(new Consumer(50, godown)).start();

new Thread(new Consumer(100, godown)).start();

new Thread(new Consumer(10, godown)).start();

new Thread(new Producer(30, godown)).start();

new Thread(new Producer(50, godown)).start();

new Thread(new Producer(10, godown)).start();

new Thread(new Producer(80, godown)).start();

new Thread(new Producer(20, godown)).start();

new Thread(new Producer(20, godown)).start();

new Thread(new Producer(30, godown)).start();

new Thread(new Consumer(100, godown)).start();

Thread.sleep(10000);

System.out.println("目前的庫存:"+godown.curNum);

}

}

class Godown{

public Integer maxSize = 1000;//庫容量

public Integer curNum ;//目前庫存

public Godown() {

}

public Godown(Integer curNum) {

super();

this.curNum = curNum;

}

public Godown(Integer maxSize, Integer curNum) {

super();

this.maxSize = maxSize;

this.curNum = curNum;

}

public synchronized void produce(Integer needNum){

//測試是夠需要生産

while(needNum+curNum>maxSize){

System.out.println("要生産的産品數量" + needNum + "超過剩餘庫存量" + (maxSize - curNum) + ",暫時不能執行生産任務!");

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//滿足條件的時候,進行生産

curNum += needNum;

System.out.println("已經生産了" + needNum + "個産品,現倉儲量為" + curNum);

//喚醒消費者

notifyAll();

}

public synchronized void consume(Integer needNum){

//測試庫存數量是夠夠實用的

while(curNum < needNum){//此處實用while的原因是因為,如果一個線程在此處等待,被喚醒後就會執行下面的代碼,跳出if,而條件可能依舊不滿足,是以讓線程醒來後繼續判斷一下,如果滿足了繼續執行,如果不滿足繼續等待

try {

System.out.println("庫存不夠,等待生産.");

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//滿足條件的時候,進行消費

curNum -= needNum;

System.out.println("已經消費了" + needNum + "個産品,現倉儲量為" + curNum);

//喚醒在此對象螢幕上等待的所有線程

notifyAll();

}

}

class Producer implements Runnable{

private Integer needNum;//要生産的數量

private Godown godown;//共享的倉庫,構造傳進來

public Producer(Integer needNum, Godown godown) {

this.needNum = needNum;

this.godown = godown;

}

@Override

public void run() {

godown.produce(needNum);//生産商品

}

}

class Consumer implements Runnable{

private Integer needNum;

private Godown godown;

public Consumer(Integer needNum, Godown godown) {

this.needNum = needNum;

this.godown = godown;

}

@Override

public void run() {

godown.consume(needNum);//消費指定數量的庫存

}

}