码迷,mamicode.com
首页 > 编程语言 > 详细

【ThinkingInJava】62、生产者与消费者

时间:2015-05-23 10:07:59      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:java编程思想   线程   消费者   生产者   

/**
* 书本:《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






【ThinkingInJava】62、生产者与消费者

标签:java编程思想   线程   消费者   生产者   

原文地址:http://blog.csdn.net/cutter_point/article/details/45932153

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!