今日看到一篇以厨师和服务员为例的,生产者消费者模型的解释,想来就顺手实现一下。首先生产者不断地生产数据就好比多个厨师不断地做菜,消费者不断地消费数据就如同服务员不断地上菜。厨师将做好的菜放到窗口等待,就如同生产者将数据放进队列后等待一样。那么我们可以简单的建立以下模型:
(1)Food模型
public class Food {
private static int counter=0;
private int i;//代表生产的第几个菜
public Food(){
i=++counter;
}
@Override
public String toString(){
return "第"+i+"个菜!";
}
}
(2)生产者厨师模型
public class Cook extends Thread{
private Queue<Food> queue;
public Cook(Queue<Food> queue,String name){
super(name);
this.queue=queue;
}
@Override
public void run(){
while(true){
SleepUtil.randomSleep();
Food food=new Food();
System.out.println(getName()+"生产了"+food);
synchronized (queue){
while(queue.size()>4){
try{
System.out.println("队列元素超过五个为:"+queue.size()+""+getName()+"抽根烟等待中");
queue.wait();
}catch (InterruptedException e){
throw new RuntimeException(e);
}
queue.add(food);
queue.notifyAll();
}
}
}
}
}
(3)消费者服务员模型
public class Waiter extends Thread{
private Queue<Food> queue;
public Waiter(Queue<Food> queue,String name){
super(name);
this.queue=queue;
}
@Override
public void run(){
while(true){
SleepUtil.randomSleep();
Food food;
synchronized (queue){
while(queue.size()<1){
try{
System.out.println("队列元素个数为:"+queue.size()+""+getName()+"抽根烟等待中");
queue.wait();
}catch (InterruptedException e){
throw new RuntimeException(e);
}
food=queue.remove();
System.out.println(getName()+"获取到:"+food);
queue.notifyAll();
}
}
}
}
}
(4)随机等待模型
public class SleepUtil {
private static Random random=new Random();
public static void randomSleep(){
try{
Thread.sleep(random.nextInt(1000));
}catch (InterruptedException e){
throw new RuntimeException(e);
}
}
}
(5)运行效果