多線程之生產者與消費者問題


之前感覺很簡單,但是有一次面試讓我在紙上寫,居然沒寫對丟人啊。

生產者消費者問題(Producer-consumer problem):生產者不斷地生產產品,消費者取走生產者生產的產品。生產者生產出產品后將其放到一個區域之中,消費者從這個地方去除數據。

涉及的問題:要保證生產者不會在緩沖區滿時加入數據,消費者也不會在緩沖區中空時消耗數據。

                 主要涉及:多線程的同步問題。

                  1、假設生產者線程剛向數據存儲空間添加了產品的名稱,還沒有添加產品的內容,程序就切到了消費者的線程,消費這的

                           線程將吧產品的名稱和上一個產品的內容聯系到了一起。

                  2、生產者放了若干次的產品,消費者才開始取產品,或者是,消費者去玩一個產品后,還沒等待生產者生產新的產品,有

                          重復的去除已經去過的產品。


其生產者消費者問題程序實現如下:

     一、產品:


[java] view plain copy
  1. package andy.thread.test;  
  2.   
  3. /** 
  4.  * @author andy 
  5.  * @version:2015-3-20 上午10:09:42 
  6.  *  
  7.  *  
  8.  */  
  9.   
  10. public class Product {  
  11.   
  12.     private String pName;  
  13.   
  14.     private String pContent;  
  15.   
  16.     private boolean flag; // 此為產品的標記 true為已有產品 false為沒有產品  
  17.   
  18.     //生產  
  19.     public synchronized void put(String pName, String pContent) {  
  20.   
  21.         if (flag) {// 如果有產品,等待消費  
  22.             try {  
  23.                 super.wait();  
  24.             } catch (InterruptedException e) {  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.   
  29.         this.setpName(pName);  
  30.           
  31.         try {  
  32.             Thread.sleep(300);  
  33.         } catch (InterruptedException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.           
  37.         this.setpContent(pContent);  
  38.         System.out.println("生產產品");  
  39.   
  40.         this.flag = true; // 標記為以生產,喚醒消費  
  41.         super.notify();  
  42.     }  
  43.   
  44.     //消費  
  45.     public synchronized void romve() {  
  46.   
  47.         if (!flag) { // 沒有產品時等待  
  48.             try {  
  49.                 super.wait();  
  50.             } catch (InterruptedException e) {  
  51.                 e.printStackTrace();  
  52.             }  
  53.         }  
  54.   
  55.         try {  
  56.             Thread.sleep(300);  
  57.         } catch (InterruptedException e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.           
  61.         System.out  
  62.                 .println("消費:" + this.getpName() + "---" + this.getpContent());  
  63.         this.flag = false; // 已消費,可以進行生產了  
  64.   
  65.         super.notify();  
  66.   
  67.     }  
  68.   
  69.     public String getpName() {  
  70.         return pName;  
  71.     }  
  72.   
  73.     public void setpName(String pName) {  
  74.         this.pName = pName;  
  75.     }  
  76.   
  77.     public String getpContent() {  
  78.         return pContent;  
  79.     }  
  80.   
  81.     public void setpContent(String pContent) {  
  82.         this.pContent = pContent;  
  83.     }  
  84.   
  85. }  

 

二、生產者

 

[java] view plain copy
  1. package andy.thread.test;  
  2.   
  3. import java.util.concurrent.TimeUnit;  
  4.   
  5. /** 
  6.  * @author andy 
  7.  * @version:2015-3-20 上午11:05:53 
  8.  *  
  9.  *  
  10.  */  
  11.   
  12. public class Producer implements Runnable {  
  13.   
  14.     private Product product = null;  
  15.   
  16.     public Producer(Product product) {  
  17.         this.product = product;  
  18.     }  
  19.   
  20.     @Override  
  21.     public void run() {  
  22.         for (int i = 0; i < 50; i++) {  
  23.   
  24.             try {  
  25.                 TimeUnit.SECONDS.sleep(5);  
  26.             } catch (InterruptedException e) {  
  27.                 e.printStackTrace();  
  28.             }  
  29.   
  30.             product.put("產品" + i, i + "");  
  31.         }  
  32.   
  33.     }  
  34.   
  35. }  

 

三、消費者

 

[java] view plain copy
  1. package andy.thread.test;  
  2.   
  3. import java.util.concurrent.TimeUnit;  
  4.   
  5. /**   
  6.  * @author andy   
  7.  * @version:2015-3-20 上午10:56:18   
  8.  *  
  9.  *   
  10.  */  
  11.   
  12. public class Consumer implements Runnable{  
  13.       
  14.     private Product product = null;  
  15.       
  16.     public Consumer(Product product){  
  17.         this.product = product;  
  18.     }  
  19.       
  20.   
  21.     @Override  
  22.     public void run() {  
  23.           
  24.         for (int i = 0; i < 50; i++) {  
  25.               
  26.             try {  
  27.                 TimeUnit.SECONDS.sleep(5);  
  28.             } catch (InterruptedException e) {  
  29.                 e.printStackTrace();  
  30.             }  
  31.               
  32.             this.product.romve();  
  33.               
  34.         }  
  35.           
  36.     }  
  37.   
  38. }  

 


測試:

 

[java] view plain copy
  1. package andy.thread.test;  
  2.   
  3. /**   
  4.  * @author andy   
  5.  * @version:2015-3-20 上午11:12:25   
  6.  *  
  7.  *   
  8.  */  
  9.   
  10. public class ConsumerProducerTest {  
  11.   
  12.     /** 
  13.      * @param args 
  14.      */  
  15.     public static void main(String[] args) {  
  16.           
  17.         Product product = new Product();  
  18.         Producer producer = new Producer(product);  
  19.         Consumer consumer = new Consumer(product);  
  20.           
  21.         new Thread(producer).start();  
  22.         new Thread(consumer).start();  
  23.           
  24.   
  25.     }  
  26.   
  27. }  

 

結果如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM