生产者与消费者模式

时间:2021-05-12 18:46:40

需求

厨子:如果食物不够:生产食物;如果食物够了,停止生产并通知客户消费
KFC食品店:存储食物
客户:如果食物够了:开始消费;如果食物不够,停止消费并等待厨子生产

步骤:

食物类
KFC类:存储食物,生产食物方法,消费食物方法
客户类:调用消费食物方法
厨子类:调用生产食物方法

代码实现

//食物类
public class Food {
public static final String[] FOOD_NAME = { "田园汉堡", "板烧鸡腿堡", "菠萝派", "薯条" };
private String name;

public String getName() {
return name;
}

public Food(String name) {
super();
this.name = name;
}
}
//KFC类
public class KFC {
// 放食物的
List<Food> list = new ArrayList<>();
// 最大数
int max = 50;

// 生产
public synchronized void productFood() {
// 食物如果够了
while (list.size() > max) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 第一次进来是没有食物的
// 第二次进来是食物的消费快完了
int number = (int) (Math.random() * 5 + 1);
for (int i = 0; i < number; i++) {
// 创建一个食物
Food food = createFood();
System.out.println(Thread.currentThread().getName() + "生产了一个" + food.getName());
list.add(food);
}
//每生产完一次食物,就唤醒所有线程
this.notifyAll();
}

private Food createFood() {
String name = Food.FOOD_NAME[(int) (Math.random() * 4)];
Food food = new Food(name);
return food;
}

// 消费
public synchronized void consumpFood() {
//生产的食物如果不够,继续等待
while (list.size() < 10) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果生产的食物够了,消费者开始消费
int num = (int) (Math.random() * 3) + 1;
for (int i = 0; i < num; i++) {
// 永远的第0个
Food food = list.remove(0);
System.out.println(Thread.currentThread().getName() + "吃掉了一个" + food.getName());
}
this.notifyAll();
}
}
//客户类
public class Customer implements Runnable{
KFC kfc;

public Customer(KFC kfc) {
this.kfc = kfc;
}

@Override
public void run() {
while (true) {
kfc.consumpFood();
//等待0.1s,增加随机性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//厨子类
public class Cooker implements Runnable {
KFC kfc;

public Cooker(KFC kfc) {
this.kfc = kfc;
}

@Override
public void run() {
while (true) {
kfc.productFood();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}