代碼主要包括4個類和1個測試類: java
一、Egg 類: 雞蛋,能夠由生產者放入到籃子中,供消費者消費食用。 dom
二、Blanket 類:一個籃子,最多能裝5個雞蛋。 ide
三、Producer 類: 生產者(能夠有1個或多個,但一次只能由一我的放入1個),負責把雞蛋放入到籃子中。 測試
四、Customer 類 :消費者(能夠有1個或多個,但一次只能由一我的吃1個), 會把籃子裏的雞蛋取走食用。 this
五、Tester 類 : 用於測試,可設置多個生產者和消費者。 spa
一、Egg類,有一個ID屬性,用於標識生產和消費的雞蛋是哪個雞蛋,直觀一點: code
public class Egg { int id; public Egg (int id) { this.id = id; } public String toString () { return "雞蛋" + id; } }
二、Blanket類,其中的放入雞蛋(add)和吃雞蛋(eat)方法使用了同步鎖,即同一時間內只能由一我的操做籃子,放入雞蛋或吃雞蛋: 繼承
public class Blanket { int count = 0; Egg [] eggs = new Egg[5]; public synchronized void eat() { while(count == 0){ try{ this.wait();//當籃子裏雞蛋數目爲0時,等待生產者放入雞蛋 }catch(InterruptedException ex) { ex.printStackTrace(); } } this.count--; System.out.println(Thread.currentThread().getName() + "吃了"+this.eggs[count].toString()); this.notifyAll(); } public synchronized void add(Egg e) { while(count == 5){ try { this.wait();//當籃子裏有5個雞蛋時,先休息 }catch(InterruptedException ex){ ex.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "生產了:" + e.toString()); this.eggs[count] = e;//生產雞蛋 count++; this.notifyAll();//喚醒消費者 } }
public class Producer implements Runnable{ Blanket blanket; public Producer(Blanket blanket) { this.blanket = blanket; } @Override public void run() { // TODO Auto-generated method stub while(true){ int i = blanket.count; Egg e = new Egg(i); blanket.add(e); try { Thread.sleep((int)(Math.random()*1000)); } catch (InterruptedException ex) { ex.printStackTrace(); } } } }
public class Customer implements Runnable { Blanket blanket; public Customer(Blanket blanket) { this.blanket = blanket; } @Override public void run() { // TODO Auto-generated method stub while(true) { blanket.eat(); try{ Thread.sleep((int)(Math.random()*2800)); }catch(InterruptedException ex){ ex.printStackTrace(); } } } }
public class Tester { public static void main(String[] args) { // TODO Auto-generated method stub Blanket b = new Blanket(); Producer p = new Producer(b); Producer q = new Producer(b); Customer c = new Customer(b); Customer d = new Customer(b); Customer e = new Customer(b); Customer f = new Customer(b); new Thread(p,"生產者A").start(); new Thread(q,"生產者B").start(); new Thread(c,"消費者A").start(); new Thread(d,"消費者B").start(); new Thread(e,"消費者C").start(); new Thread(f,"消費者D").start(); } }
生產者A生產了:雞蛋0 消費者A吃了雞蛋0 生產者B生產了:雞蛋0 消費者B吃了雞蛋0 生產者A生產了:雞蛋0 消費者D吃了雞蛋0 生產者A生產了:雞蛋0 消費者C吃了雞蛋0 生產者A生產了:雞蛋0 生產者B生產了:雞蛋1 消費者D吃了雞蛋1 生產者B生產了:雞蛋1 生產者A生產了:雞蛋2 生產者A生產了:雞蛋3 生產者A生產了:雞蛋4 消費者B吃了雞蛋4 生產者B生產了:雞蛋5 消費者A吃了雞蛋5 生產者A生產了:雞蛋5 消費者B吃了雞蛋5它將不停的運行下去,不會出現死鎖。代碼的同步(synchronized)模塊設置在共用的資源(籃子)中,每次只能由一名生產者或者消費者操做籃子,其餘人處於等待(wait)狀態,等它操做完了,它才通知其餘人(notifyAll),其它人則經過競爭,而後只有一個競爭勝利的能夠操做籃子,如此循環。