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

Posted blfbuaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程之生产者与消费者问题相关的知识,希望对你有一定的参考价值。

之前感觉非常easy,可是有一次面试让我在纸上写,竟然没写对丢人啊。

生产者消费者问题(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();
		

	}

}

结果例如以下:

技术分享










以上是关于多线程之生产者与消费者问题的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之多线程

多线程之生产者与消费者

(王道408考研操作系统)第二章进程管理-第三节6:经典同步问题之生产者与消费者问题

(王道408考研操作系统)第二章进程管理-第三节7:经典同步问题之多生产者与多消费者问题

Java并发程序设计设计模式与并发之生产者-消费者模式

多线程之生产者和消费者模式