多线程之生产者与消费者问题

之前感觉很简单,但是有一次面试让我在纸上写,居然没写对丢人啊。

生产者消费者问题(Producer-consumer problem):生产者不断地生产产品,消费者取走生产者生产的产品。生产者生产出产品后将其放到一个区域之中,消费者从这个地方去除数据。

涉及的问题:要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

                 主要涉及:多线程的同步问题。

                  1、假设生产者线程刚向数据存储空间添加了产品的名称,还没有添加产品的内容,程序就切到了消费者的线程,消费这的

                           线程将吧产品的名称和上一个产品的内容联系到了一起。

                  2、生产者放了若干次的产品,消费者才开始取产品,或者是,消费者去玩一个产品后,还没等待生产者生产新的产品,有

                          重复的去除已经去过的产品。


其生产者消费者问题程序实现如下:

     一、产品:


  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. }  

 

二、生产者

 

  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. }  

 

三、消费者

 

  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. }  

 


测试:

 

  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. }  

 

结果如下:

posted on 2016-07-21 11:45  夏天的早餐  阅读(2374)  评论(1编辑  收藏  举报

导航