瞭解完線程交互和線程同步後,寫下來看一個綜合的例子——生產者消費者java
//生產者 public class Producer extends Thread { private int neednum; private Godown godown; Producer(int neednum, Godown godown){ this.neednum = neednum; this.godown = godown; } @Override public void run() { godown.produce(neednum); } } //消費者 public class Consumer extends Thread { private int neednum; private Godown godown; Consumer(int neednum, Godown godown){ this.neednum = neednum; this.godown = godown; } @Override public void run() { godown.consume(neednum); } } //倉庫 public class Godown { public static final int max_size = 100; public int curnum; public static void main(String[] args) { Godown godown = new Godown(30); Consumer c1 = new Consumer(50, godown); Consumer c2 = new Consumer(20, godown); Consumer c3 = new Consumer(30, godown); Producer p1 = new Producer(10, godown); Producer p2 = new Producer(10, godown); Producer p3 = new Producer(10, godown); Producer p4 = new Producer(10, godown); Producer p5 = new Producer(10, godown); Producer p6 = new Producer(10, godown); Producer p7 = new Producer(80, godown); c1.start(); c2.start(); c3.start(); p1.start(); p2.start(); p3.start(); p4.start(); p5.start(); p6.start(); p7.start(); } 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(); } } //結果 已經消費了20個產品,現倉儲量爲10 已經生產了10個產品,現倉儲量爲20 已經生產了10個產品,現倉儲量爲30 已經消費了30個產品,現倉儲量爲0 已經生產了10個產品,現倉儲量爲10 已經生產了10個產品,現倉儲量爲20 已經生產了10個產品,現倉儲量爲30 已經生產了10個產品,現倉儲量爲40 要生產的產品數量80超過剩餘庫存量60 暫時不能執行生產任務 !
例子參考:http://lavasoft.blog.51cto.com/62575/221932ide
上面的例子使用同步方法實現的,下面咱們使用同步代碼塊實現。this
public class Producer extends Thread { private int neednum; private Godown godown; Producer(int neednum, Godown godown) { this.neednum = neednum; this.godown = godown; } @Override public void run() { synchronized (this) { while (neednum + godown.getCurnum() >= Godown.max_size) { System.out.println("要生產的產品數量" + neednum + "超過剩餘庫存量" + (Godown.max_size - godown.getCurnum()) + " 暫時不能執行生產任務 !"); try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //知足生產條件,則進行生產 godown.setCurnum(godown.getCurnum() + neednum); System.out.println("已經生產了" + neednum + "個產品,現倉儲量爲" + godown.getCurnum()); notifyAll(); } } } public class Consumer extends Thread { private int neednum; private Godown godown; Consumer(int neednum, Godown godown){ this.neednum = neednum; this.godown = godown; } @Override public void run() { synchronized (this){ while (godown.getCurnum() < neednum) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } godown.setCurnum(godown.getCurnum() - neednum); System.out.println("已經消費了" + neednum + "個產品,現倉儲量爲" + godown.getCurnum()); notifyAll(); } } } public class Godown { public static final int max_size = 100; public int curnum; public int getCurnum() { return curnum; } public void setCurnum(int curnum) { this.curnum = curnum; } public static void main(String[] args) { Godown godown = new Godown(30); Consumer c1 = new Consumer(50, godown); Consumer c2 = new Consumer(20, godown); Consumer c3 = new Consumer(30, godown); Producer p1 = new Producer(10, godown); Producer p2 = new Producer(10, godown); Producer p3 = new Producer(10, godown); Producer p4 = new Producer(10, godown); Producer p5 = new Producer(10, godown); Producer p6 = new Producer(10, godown); Producer p7 = new Producer(80, godown); c1.start(); c2.start(); c3.start(); p1.start(); p2.start(); p3.start(); p4.start(); p5.start(); p6.start(); p7.start(); } Godown(int curnum) { this.curnum = curnum; } }