多线程之生产者与消费者问题
之前感觉很简单,但是有一次面试让我在纸上写,居然没写对丢人啊。
生产者消费者问题(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();
- }
- }
结果如下: