多線程:哲學家進餐問題。

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多線程學習--哲學家就餐問題 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章