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

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

生產者消費者問題(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();
		

	}

}

結果如下:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章