之前感觉很简单,但是有一次面试让我在纸上写,居然没写对丢人啊。
生产者消费者问题(Producer-consumer problem):生产者不断地生产产品,消费者取走生产者生产的产品。生产者生产出产品后将其放到一个区域之中,消费者从这个地方去除数据。
涉及的问题:要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
主要涉及:多线程的同步问题。
1、假设生产者线程刚向数据存储空间添加了产品的名称,还没有添加产品的内容,程序就切到了消费者的线程,消费这的
线程将吧产品的名称和上一个产品的内容联系到了一起。
2、生产者放了若干次的产品,消费者才开始取产品,或者是,消费者去玩一个产品后,还没等待生产者生产新的产品,有
重复的去除已经去过的产品。
其生产者消费者问题程序实现如下:
一、产品:
package andy.thread.test; /** * @author andy * @version:2015-3-20 上午10:09:42 * * */ public class Product { private String pName; private String pContent; private boolean flag; // 此为产品的标记 true为已有产品 false为没有产品 //生产 public synchronized void put(String pName, String pContent) { if (flag) {// 如果有产品,等待消费 try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.setpName(pName); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } this.setpContent(pContent); System.out.println("生产产品"); this.flag = true; // 标记为以生产,唤醒消费 super.notify(); } //消费 public synchronized void romve() { if (!flag) { // 没有产品时等待 try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out .println("消费:" + this.getpName() + "---" + this.getpContent()); this.flag = false; // 已消费,可以进行生产了 super.notify(); } public String getpName() { return pName; } public void setpName(String pName) { this.pName = pName; } public String getpContent() { return pContent; } public void setpContent(String pContent) { this.pContent = pContent; } }
二、生产者
package andy.thread.test; import java.util.concurrent.TimeUnit; /** * @author andy * @version:2015-3-20 上午11:05:53 * * */ public class Producer implements Runnable { private Product product = null; public Producer(Product product) { this.product = product; } @Override public void run() { for (int i = 0; i < 50; i++) { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } product.put("产品" + i, i + ""); } } }
三、消费者
package andy.thread.test; import java.util.concurrent.TimeUnit; /** * @author andy * @version:2015-3-20 上午10:56:18 * * */ public class Consumer implements Runnable{ private Product product = null; public Consumer(Product product){ this.product = product; } @Override public void run() { for (int i = 0; i < 50; i++) { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } this.product.romve(); } } }
测试:
package andy.thread.test; /** * @author andy * @version:2015-3-20 上午11:12:25 * * */ public class ConsumerProducerTest { /** * @param args */ public static void main(String[] args) { Product product = new Product(); Producer producer = new Producer(product); Consumer consumer = new Consumer(product); new Thread(producer).start(); new Thread(consumer).start(); } }
结果如下:
原文地址:http://blog.csdn.net/fengshizty/article/details/44488987