1. 程式人生 > 其它 >多執行緒之生產者消費者問題

多執行緒之生產者消費者問題

生產者消費者問題介紹

生產者消費者問題是一個經典的多執行緒同步問題。該問題描述了兩個程序——即所謂的“生產者”和“消費者”——在實際執行時會發生的問題。生產者的主要作用是不斷的生成資料,而與此同時,消費者則不斷消耗這些資料。該問題的關鍵就是要保證當生產者生產了產品後,若消費者還沒有消費此產品,則生產者停止生產並等待,直到消費者消費了此產品;當消費者消費了產品後,若生產者還沒有及時生產新的產品,則消費者停止消費並等待,直到生產者生產了新產品。

存在的問題

  • 當生產者比消費者快時,消費者會漏掉一部分資料
  • 當消費者比生產者快時,消費者會取走重複的資料

使用 wait() 和 notify() 方法

wait():當緩衝區已滿 / 空時,生產者或消費者執行緒停止自己的執行,釋放鎖,使自己處於等待狀態,讓其它執行緒執行。

notify():當生產者或消費者向緩衝區放入或取出一個產品時,向其他等待的執行緒發出通知,同時釋放鎖,使自己處於等待狀態,讓其它執行緒執行。

 1 public class Demo04_生成者消費者 {
 2 
 3     public static void main(String[] args) {
 4         new Producer().start();
 5         new Consumer().start();
 6     }
 7 
 8
private static List<Integer> hamburgers = new ArrayList<Integer>(); 9 10 private static class Producer extends Thread{ //生產者 11 12 int i=0; 13 14 public void run() { 15 16 while(true){ 17 if(hamburgers.size()<10){ 18 hamburgers.add(i); //
生產 19 System.out.println("生產漢堡: "+i); 20 i++; 21 22 synchronized (hamburgers) { 23 hamburgers.notifyAll(); 24 } 25 26 }else{ 27 synchronized (hamburgers) { 28 try { 29 hamburgers.wait(); 30 } catch (InterruptedException e) { 31 e.printStackTrace(); 32 } 33 } 34 35 } 36 37 try { 38 Thread.sleep(200); 39 } catch (InterruptedException e) { 40 e.printStackTrace(); 41 } 42 } 43 } 44 } 45 46 private static class Consumer extends Thread{//消費者 47 public void run() { 48 while(true){ 49 if(hamburgers.size()>0){ 50 System.out.println("消費漢堡: "+hamburgers.remove(0)); // 消費 51 52 synchronized (hamburgers) { 53 hamburgers.notifyAll(); 54 } 55 56 }else{ 57 synchronized (hamburgers) { 58 59 try { 60 hamburgers.wait(); 61 } catch (InterruptedException e) { 62 // TODO Auto-generated catch block 63 e.printStackTrace(); 64 } 65 } 66 } 67 68 try { 69 Thread.sleep(200); 70 } catch (InterruptedException e) { 71 e.printStackTrace(); 72 } 73 } 74 } 75 } 76 }