/**
* 书本:《Thinking In Java》
* 功能:生产者与消费者:
* 请考虑这样一个人饭店,它有一个厨师和一个服务员。这个服务员必须等待厨师准备好膳食。当厨师准备好时,他会通知服务员,之后服务员上菜,然后返回继续等待。
* 文件:Restaurant.java
* 时间:2015年5月8日18:23:01
* 作者:cutter_point
*/
package Lesson21Concurency;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static net.mindview.util.Print.*;
class Meal //膳食类
{
private final int orderNum; //点餐的数量
public Meal(int orderNum) { this.orderNum = orderNum; } //初始化,餐点的数量
public String toString() { return "Meal " + this.orderNum; }
}
//客人类
class WaitPerson implements Runnable
{
private Restaurant restaurant; //一个餐厅类
public WaitPerson(Restaurant r) { restaurant = r; } //构造函数,客人要去的餐厅在哪?
@Override
public void run()
{
//对于一个客人来说,就是等待自己的食物
try
{
while(!Thread.interrupted()) //只要线程没有被中断
{
synchronized(this) //当取得了客人这个线程的时候
{
while(restaurant.meal == null) //没有食物了
this.wait(); //等待厨师做好食物
}
print("客人得到了 " + restaurant.meal); //客人得到了食物,准备吃饭
synchronized(restaurant.chef)
{
restaurant.meal = null; //食物买完了
restaurant.chef.notifyAll(); //食物卖完了,唤醒厨师赶紧做食物
}
}
}
catch (InterruptedException e)
{
print("客人没食物吃,走了!");
}
}
}
class Chef implements Runnable
{
private Restaurant restaurant; //厨师所在的餐厅
private int count = 0;
public Chef(Restaurant restaurant)
{
this.restaurant = restaurant;
}
@Override
public void run()
{
//首先线程不能被中断
try
{
while(!Thread.interrupted())
{
//当线程没有被中断的时候
synchronized(this) //给这个块上锁,当没有得到当前对象的锁的时候,不能执行
{
while(restaurant.meal != null)
this.wait(); //线程进入等待,只要还有食物,那么就得等待
}
//当被调用了10次的时候,那么就说食物吃完了,关门大吉
if(++count == 10)
{
print("食物卖完了,关门大吉");
//停止线程
// restaurant.exec.shutdown();
restaurant.exec.shutdownNow(); //这个函数是向所有的由ExecutorService启动的任务发送interrupt中断请求
}
printnb("上菜啦!"); //当没有被调用10次的时候,还有食物
synchronized(restaurant.waitPerson) //当线程取得这个餐厅里面的客人对象的时候
{
restaurant.meal = new Meal(count); //生产第count套食物
restaurant.waitPerson.notifyAll(); //唤醒客人,可以开始吃饭了
}
TimeUnit.MILLISECONDS.sleep(100); //休息100毫秒
}
}
catch (InterruptedException e)
{
print("厨师被炒鱿鱼了!");
}
}
}
//餐厅类
public class Restaurant
{
//餐厅里面有食物,客人,服务员
Meal meal;
//线程连接池
ExecutorService exec = Executors.newCachedThreadPool();
WaitPerson waitPerson = new WaitPerson(this);
Chef chef = new Chef(this);
//好的,食物有了,客人有了,厨师也有了,这个餐厅擦不多可以运作了
//创建一个餐厅之后,投入运行
public Restaurant()
{
//用线程连接池,一起运作这三个线程
exec.execute(chef); //厨师投入工作
exec.execute(waitPerson); //来了客人
}
public static void main(String[] args)
{
new Restaurant(); //投入建立一家餐厅
}
}
输出:
上菜啦!-obj2 客人得到了 Meal 1 obj1
上菜啦!-obj2 客人得到了 Meal 2 obj1
上菜啦!-obj2 客人得到了 Meal 3 obj1
上菜啦!-obj2 客人得到了 Meal 4 obj1
上菜啦!-obj2 客人得到了 Meal 5 obj1
上菜啦!-obj2 客人得到了 Meal 6 obj1
上菜啦!-obj2 客人得到了 Meal 7 obj1
上菜啦!-obj2 客人得到了 Meal 8 obj1
上菜啦!-obj2 客人得到了 Meal 9 obj1
食物卖完了,关门大吉 obj1
上菜啦!-obj2 客人没食物吃,走了! obj1
厨师被炒鱿鱼了! obj1