Java 經典例題:生產者/消費者問題
阿新 • • 發佈:2018-12-18
Java 經典例題:生產者/消費者問題
1. 問題
- 生產者(Productor)將產品交給店員(Clerk),而消費者(Customer)從店員處取走產品,店員一次只能持有固定數量的產品(比如:20),如果生產者試圖生產更多的產品,店員會叫生產者停一下,如果店中有空位放產品了再通知生產者繼續生產;如果店中沒有產品了,店員會告訴消費者等一下,如果店中有產品了再通知消費者來取走產品。
2.分析
- 是否涉及到多執行緒的問題?
生產者、消費者 - 是否涉及到共享資料?
有!需考慮執行緒的安全 - 此共享資料為?
及為產品的數量 - 是否涉及到執行緒的通訊?
存在,生產者與消費者的通訊
3.demo
class Clerk{//店員 int product;//共享資料 public synchronized void addProduct() {//生產產品 if(product >=20) { try { wait();//掛起執行緒 } catch (InterruptedException e) { e.printStackTrace(); } }else { product++; System.out.println(Thread.currentThread().getName()+":生產了第"+product+"產品"); notify();//既然已經產品大於0小於20了,那個就喚醒消費者的執行緒 } } public synchronized void consumeProduct() {//消費產品 if(product <=0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else { System.out.println(Thread.currentThread().getName()+":消費了第"+product+"產品"); product--; notify(); } } } class Producer implements Runnable{//生產者 Clerk clerk; public Producer(Clerk clerk) { this.clerk = clerk; } public void run () {//搶到資源執行的方法 System.out.println("生產者開始生產產品"); while(true) { try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } clerk.addProduct(); } } } class Consumer implements Runnable{ Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } public void run() {//搶到資源執行的方法 System.out.println("消費者開始消費產品"); while(true) { try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } clerk.consumeProduct(); } } } public class TestProduceConsume { public static void main(String[] args) { Clerk clerk = new Clerk(); Producer p1 = new Producer(clerk); Consumer c1 = new Consumer(clerk); Thread t1 = new Thread(p1);//一個生產者的執行緒 Thread t3 = new Thread(p1);//一個生產者的執行緒 Thread t2 = new Thread(c1);//一個消費者的執行緒 t1.setName("生產者1"); t3.setName("生產者2"); t2.setName("消費者2"); t1.start(); t2.start(); t3.start(); } }
- 輸出