哲学家就餐问题

import java.util.Random;

/*
 * 问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。
 * 哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭。
 * 上述问题会产生死锁的情况,当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象。
 */
/*
 * 解决办法:
  1、添加一个服务生,只有当经过服务生同意之后才能拿筷子,服务生负责避免死锁发生。
  2、每个哲学家必须确定自己左右手的筷子都可用的时候,才能同时拿起两只筷子进餐,吃完之后同时放下两只筷子。
  3、规定每个哲学家拿筷子时必须拿序号小的那只,这样最后一位未拿到筷子的哲学家只剩下序号大的那只筷子,
                 不能拿起,剩下的这只筷子就可以被其他哲学家使用,避免了死锁。这种情况不能很好的利用资源。 
 */
class Forks{
	private int size;
	private boolean[] isUsed;
	public Forks(int size) {
		// TODO Auto-generated constructor stub
		this.size = size;
		isUsed = new boolean[size];
	}
	public synchronized void getForks(){
		int id = Integer.parseInt(Thread.currentThread().getName());//检测是哪个线程
		while (isUsed[id] || isUsed[(id+1)%size]) {//左右手边有筷子已经被使用了
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		}
		isUsed[id] = true;
		isUsed[(id+1)%size] = true;
		System.out.println(id+":I have getten forks:"+id+","+(id+1)%size);
	}
	public synchronized void putDownForks(){
		int id = Integer.parseInt(Thread.currentThread().getName());//检测是哪个线程
		isUsed[id] = false;
		isUsed[(id+1)%size] = false;
		System.out.println(id+":I have putdown forks:"+id+","+(id+1)%size);
		notifyAll();
	}
}
//每个哲学家线程
class Philosopher extends Thread{
	private String id;//编号
	private Forks forks;//共用的叉子
	public Philosopher(String id,Forks forks){
		this.id = id;
		this.forks = forks;
		this.setName(id);
	}
	//模拟思考
	public void think(){
		System.out.println(id+":I am thinking!");
		Random random = new Random();
		try {
			Thread.sleep(random.nextInt(4)*1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//模拟就餐
	public void eating(){
		forks.getForks();//先获取左右两边叉子
		System.out.println(id+":I am eating!");//开始吃饭
		Random random = new Random();
		try {
			Thread.sleep(random.nextInt(4)*1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		forks.putDownForks();//放下叉子
	}
	 @Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			think();
			eating();
			
		}
	}
}

public class 哲学家进餐问题 {

	public static void main(String[] args) {
		final int NUM_OF_PH = 5;
		Forks forks = new Forks(NUM_OF_PH);
		for (int i = 0; i < NUM_OF_PH; i++) {			
			new Philosopher(""+i, forks).start();
		}
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值