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();
}
}
}
}