幽靈工作室提供
對于多線程程式來說,不管任何程式設計語言,生産者和消費者模型都是最經典的。就像學習每一門程式設計語言一樣,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);//消費指定數量的庫存
}
}