1. 程式人生 > >黑馬程式設計師技術部落格之哲學家吃飯問題

黑馬程式設計師技術部落格之哲學家吃飯問題

----------- android培訓java培訓、java學習型技術部落格、期待與您交流! ------------

哲學家就餐:有五個哲學家繞著圓桌坐,每個哲學家面前有一碗麵,兩人之間有一支筷子,這樣每個哲學家左右各有一支筷子。哲學家有2個狀態,思考或者拿起筷子吃飯。如果哲學家拿到一隻筷子,不能吃飯,直到拿到2只才能吃飯,並且一次只能拿起身邊的一支筷子。一旦拿起便不能放下直到把飯吃完,此時才把這雙筷子放回原處。如果,很不幸地,每個哲學家拿起他或她左邊的筷子,那麼就沒有人可以吃到飯了。這就會造成了死鎖……

我試著編了程式碼,但只能一個人吃,不知道在保證不死鎖的情況下怎樣才能讓兩個人同時吃。

import java.util.concurrent.locks.*;
public class PhilosopherProblem {
	public static void main(String[] args){
		Fork f1=new Fork("叉子一號");
		Fork f2=new Fork("叉子二號");
		Fork f3=new Fork("叉子三號");
		Fork f4=new Fork("叉子四號");
		Fork f5=new Fork("叉子五號");
		Lock lock = new ReentrantLock();
		Food food = new Food(100);
		new Thread(new Philosopher("哲學家A",f1,f2,lock,food)).start();
		new Thread(new Philosopher("哲學家B",f2,f3,lock,food)).start();
		new Thread(new Philosopher("哲學家C",f3,f4,lock,food)).start();
		new Thread(new Philosopher("哲學家D",f4,f5,lock,food)).start();
		new Thread(new Philosopher("哲學家E",f5,f1,lock,food)).start();
	}
}
//Food類
class Food{
	int food;
	public Food(int food){
		this.food = food;
	}
	public int eat(){
		return food--;
	}
	public int has(){
		return food;
	}
}
//叉子類
class Fork{
	String name;
	boolean flag=true;//構造方法
	public Fork(String name){
		this.name=name;
	}
	//放下叉子
	public synchronized void putdown(){
		this.flag=true;
		this.notifyAll();
	}
	//去取叉子
	public synchronized void pickup(){
		try{
			while(flag==false){
				this.wait();
			}
		this.flag=false;
		}
		catch(Exception e){}
	}
}
//哲學家類:
class Philosopher implements Runnable{
	String name;
	Fork left;
	Fork right;
	Lock lock;
	Food food;
	public Philosopher(String name,Fork left,Fork right,Lock lock,Food food){
		this.name = name;
		this.left = left;
		this.right = right;
		this.lock = lock;
		this.food = food;
	}
	public void run(){
		//吃飯前的思考,時間是隨機的
		while(true){
			try{
				System.out.println(name+"在思考中。。。");
				Thread.sleep((long)(Math.random()*10));//思考時間
				System.out.println(name+"思考結束!");
			}
			catch(InterruptedException e){
				e.printStackTrace();
			}
			lock.lock();
			left.pickup();
			System.out.println(name+"抓起"+left.name);
			right.pickup();
			System.out.println(name+"抓起"+right.name);
			if(food.has()>0){
				System.out.println(name+"拿到兩支叉子開吃:"+food.eat());
				lock.unlock();
			}
			else{
				lock.unlock();
				System.out.println(name+"……food已經被吃完了");
				left.putdown();
				right.putdown();
				break;
			}
			try{
				Thread.sleep(20);//吃飯時間
			}
			catch(InterruptedException e){
				e.printStackTrace();
			}
			System.out.println(name+"吃飽之後放下了"+left.name+"和"+right.name+"!");
			left.putdown();
			right.putdown();
		}
	System.out.println(name+"……gameover");
	}
}
這個問題,看了網上也有一些解決方案,但是感覺都挺繁瑣的。