多线程:哲学家进餐问题。

5个哲学家共用一张圆桌,分别坐在周围的5张椅子上,在圆桌上有5个碗和5只筷子(注意是5只筷子,不是5双),碗和筷子交替排列。他们的生活方式是交替地进行思考(thinking)和进餐(eating)。

平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的两只筷子,规定他必须先取左边的筷子,再取右边的筷子。
只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续进行思考。

假如5位哲学家同时饥饿,各自拿起左边的筷子时,再去拿各自右边的筷子,因为无筷子可拿而陷入无期限等待(死锁)。

进餐完毕释放他用过的两只筷子,从而使更多的哲学家能够进餐。使用Java的多线程同步技术,实现上述解决方案。

破坏请求和保持条件

方案:仅当一个哲学家左右两边的叉子都可用时才允许他抓起叉子,即破坏死锁四大条件之一——请求和保持条件

说明白点就是,不会出现某个哲学家拿一个筷子等一个筷子的情况,必须同时拿两个!

package philosopher;

public class ThreadTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Chop fiveChops = new Chop();
		new Philosopher(0,fiveChops).start();
		new Philosopher(1,fiveChops).start();
		new Philosopher(2,fiveChops).start();
		new Philosopher(3,fiveChops).start();
		new Philosopher(4,fiveChops).start();
	}

}


class Philosopher extends Thread{
	private int index;
	private Chop chop;
	public Philosopher(int index, Chop chop) {
		// TODO Auto-generated constructor stub
		this.index = index;
		this.chop = chop;
	}
	
	@Override
	public void run() {
		while(true) {
			thinking();
			chop.takeChop(index);
			eating();
			chop.putChop(index);
		}
	}
	private void thinking(){
		// TODO Auto-generated method stub
		System.out.println("第"+index + "个哲学家正在思考...");
		try {
			sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void eating(){
		// TODO Auto-generated method stub
		System.out.println("第"+index + "个哲学家正在吃饭...");
		try {
			sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}


class Chop {
	private Boolean[] chops = {false,false,false,false,false};

	public synchronized void takeChop(int index) {
		// TODO Auto-generated method stub
		while(chops[index] || chops[(index+1)%5]) {
			try {
				wait(); //拿不到筷子就会被阻塞 进入等待池 从而不会再来竞争
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		chops[index] = true;
		chops[(index+1)%5] = true;
	}

	public synchronized void putChop(int index) {
		// TODO Auto-generated method stub
		chops[index] = false;
		chops[(index+1)%5] = false;
		notifyAll();
	}
	
}

参考文章: 
[1] sunny_ss12 经典同步问题(二)---哲学家就餐问题 
[2] Yun_Ge PV操作经典例题——哲学家进餐问题 
[3] qiuhuilu JAVA多线程学习--哲学家就餐问题 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值