生產者消費者模式

package com.ck.Threads;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 生產者消費者模式
 * 
 * @author sansheng__
 *
 */
public class ConsumerAndProducer {

	public static void main(String[] args) {
                //食物隊列
		Queue<Food> queue = new LinkedList<Food>();
		int maxSize = 10;

		Producer producer = new Producer(queue, maxSize,"李大嘴");
		Consumer consumer1 = new Consumer(queue,"白展堂");
		Consumer consumer2 = new Consumer(queue,"佟湘玉");
		Consumer consumer3 = new Consumer(queue,"郭芙蓉");

		producer.start();
		consumer1.start();
		consumer2.start();
		consumer3.start();
	}

}

/**
 * 生產者
 */
class Producer extends Thread {
	private Queue<Food> queue;
	private int maxSize;
	private String name;

	public Producer() {
		super();
	}

	public Producer(Queue<Food> queue, int maxSize, String name) {
		super();
		this.queue = queue;
		this.maxSize = maxSize;
		this.name = name;
	}


	@Override
	public void run() {
		this.setName(this.name);
		while (true) {
			// 將食物隊列鎖住
			synchronized (queue) {
				// 模擬時延
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				// 當食物隊列滿了,停止生產食物
				while (queue.size() == maxSize) {
					try {
						queue.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				Food food = new Food("包子");
				queue.add(food);
				System.out.println(this.getName() + "生產食物:" + food.getName());
				// 喚醒消費者
				queue.notifyAll();
			}
		}
	}

}

/**
 * 消費者
 */
class Consumer extends Thread {
	private Queue<Food> queue;
	private String name;
	
	public Consumer() {
		super();
	}

	public Consumer(Queue<Food> queue, String name) {
		super();
		this.queue = queue;
		this.name = name;
	}



	@Override
	public void run() {
		this.setName(this.name);
		while (true) {
			// 將食物隊列鎖住
			synchronized (queue) {
				// 模擬時延
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				// 當食物隊列空了,停止消費食物
				//這裏一定要用while,因爲當生產者生產食物後,會喚醒所有消費者,如果是if的話,被喚醒的消費者不會再去判斷食物隊列是否爲空就會出現錯誤,
				//while會讓消費者重新判斷食物是否爲空,再去執行是消費食物還是繼續等待
				while (queue.isEmpty()) {
					try {
						queue.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				Food food = queue.poll();
				System.out.println(this.getName() + "消費食物:" + food.getName());
				// 喚醒提供者
				queue.notifyAll();
			}
		}
	}

}

 

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