一、生產/消費者模型多線程
生產/消費者模型是一個典型的多線程問題,涉及到的對象包括「生產者」、「消費者」、「倉庫」和「產品」。它們之間的關係以下;
(01)生產者僅僅在倉庫未滿的時候生產,倉庫滿了則中止生產this
(02)消費者僅僅在倉庫有產品的時候才能消費,倉庫空則等待spa
(03)當消費者發現倉庫沒有產品的時候會通知生產者生產線程
(04)生產者在生產出可消費的產品時,應該通知等待的消費者去消費code
二、實現對象
class Depot { private int capacity; //倉庫容量 private int size; //倉庫的實際數量 public Depot(int capacity) { this.capacity = capacity; this.size = 0; } public synchronized void produce(int val) { try { int left = val; //表示想要生產的數量 while(left > 0) { while(size >= capacity) //倉庫滿了,等待消費者 wait(); //計算實際增量 //若是庫存+想要生產的數量 > 容量,則「實際增量」 = 「容量」 - 「當前容量」(這樣會填滿倉庫) //不然,增量 = 想要生產的數量 int increment = (size+left) > capacity ? (capacity-size) : left; size = size + increment; left = left - increment; System.out.printf("%S produce(%d) --> left = %d,inc = %d, size = %d\n", Thread.currentThread().getName(),val,left,increment,size); notifyAll(); } } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void consume(int val) { try { int left = val; while(left > 0) { while(size <= 0) wait(); int decrement = size < left ? size : left; size = size - decrement; left = left - decrement; System.out.printf("%s consume(%d) <-- left = %d, dec = %d, size = %d\n", Thread.currentThread().getName(),val,left,decrement,size); notifyAll(); } } catch (InterruptedException e) { e.printStackTrace(); } } public String toString() { return "capacity:"+capacity+", actual size:"+size; } } class Customer { private Depot depot; public Customer(Depot depot) { this.depot = depot; } public void consume(final int val) { new Thread() { public void run() { depot.consume(val); } }.start(); } } class Producer { private Depot depot; public Producer(Depot depot) { this.depot = depot; } public void produce(final int val) { new Thread() { public void run() { depot.produce(val); } }.start(); } } public class Demo { public static void main(String[] args) { Depot mDepot = new Depot(100); Producer mPro = new Producer(mDepot); Customer mCus = new Customer(mDepot); mPro.produce(60);; mPro.produce(120); mCus.consume(90); mCus.consume(150); mPro.produce(110); } }
運行結果:blog
THREAD-0 produce(60) --> left = 0,inc = 60, size = 60 THREAD-4 produce(110) --> left = 70,inc = 40, size = 100 Thread-3 consume(150) <-- left = 50, dec = 100, size = 0 THREAD-1 produce(120) --> left = 20,inc = 100, size = 100 Thread-2 consume(90) <-- left = 0, dec = 90, size = 10 Thread-3 consume(150) <-- left = 40, dec = 10, size = 0 THREAD-4 produce(110) --> left = 0,inc = 70, size = 70 Thread-3 consume(150) <-- left = 0, dec = 40, size = 30 THREAD-1 produce(120) --> left = 0,inc = 20, size = 50
五個線程都把本身想生產或者想消費的執行完畢ci