關於執行緒的 管程
阿新 • • 發佈:2022-01-07
關於執行緒的 管程
引用狂神說
簡單的說消費者與生產這互相成為約束,建立快取區 ,利用緩衝的限制來控制消費者與生產者
生產者
// 生產者 class Productor extends Thread{ SynContainer container; public Productor(SynContainer container){ this.container=container; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("生產了"+i+"雞"); container.push(new Chicken(i)); } } }
建立建構函式。引入緩衝,run方法中進行執行函式體,呼叫緩衝的增加方法
消費者
//消費者 class Consumer extends Thread{ SynContainer container; public Consumer(SynContainer container){ this.container=container; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("消費"+container.pop().id+"雞"); } } }
同理消費者,消費者在建構函式中引入緩衝,呼叫緩衝的減少方法
生產資料
class Chicken{
int id;
public Chicken(int id) {
this.id=id;
}
}
關於容器
class SynContainer{ //容器的大小 Chicken [] chickens=new Chicken[10]; //容器計數器 int count=0; //生產者放入產品 public synchronized void push(Chicken chicken){ //判斷容器的清空,滿了通知消費,未滿繼續丟入 if(count==chickens.length){ //通知消費,生產者等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } chickens[count]=chicken; count++; //通知消費這進行消費 啟用指定物件上掛起的所有執行緒 this.notifyAll(); } //消費者取走產品 public synchronized Chicken pop(){ if(count==0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } count--; Chicken chicken=chickens[count]; //通知進行生產,啟用等待執行緒 this.notifyAll(); return chicken; }
pop 方法與 push 方法互相影響,作為SynContainer其this.notifyAll()激活了對面的wait,掛起執行緒如此
public class Testpc {
public static void main(String[] args) {
SynContainer synContainer=new SynContainer();
new Productor(synContainer).start();
new Consumer(synContainer).start();
}
}
啟動完成預期功能
生產了0雞
生產了1雞
生產了2雞
生產了3雞
生產了4雞
生產了5雞
生產了6雞
生產了7雞
生產了8雞
生產了9雞
生產了10雞
生產了11雞
消費0雞
消費10雞
生產了99雞
消費98雞
消費99雞
消費7雞
消費6雞
消費5雞
消費4雞
消費3雞
消費2雞
消費1雞
程序速度差不多導致的結果很有趣(部分擷取控制檯結果)