JAVA多線程解決哲學家就餐問題
哲學家進餐問題:5個哲學家共用一張圓桌,分別坐在周圍的5張椅子上,在圓桌上有5個碗和5只筷子(注意是5只筷子,不是5雙),碗和筷子交替排列。他們的生活方式是交替地進行思考(thinking)和進餐(eating)。平時,一個哲學家進行思考,飢餓時便試圖取用其左右最靠近他的兩隻筷子,規定他必須先取左邊的筷子,再取右邊的筷子。只有在他拿到兩隻筷子時才能進餐。進餐完畢,放下筷子繼續進行思考。假如5位哲學家同時飢餓,各自拿起左邊的筷子時,再去拿各自右邊的筷子,因爲無筷子可拿而陷入無期限等待(死鎖)。一種解決的辦法是:至多隻允許有4位哲學家同時去拿左邊的筷子,最終能保證至少有一位哲學家能夠拿到兩隻筷子,從而進餐。進餐完畢釋放他用過的兩隻筷子,從而使更多的哲學家能夠進餐。使用Java的多線程同步技術,實現上述解決方案。
- 從上面圖片可以看出,若哲學家編號爲member,則他的左筷子編號是member%5;右筷子編號爲(mem+5-1)%5,當然你也可以有自己的編號設置。上面只是一種參考。*
package Test3;
import java.util.Random;
class Canzhuo4 implements Runnable{
static Object []a={1,2,3,4,5}; //筷子數組
private int mem; //哲學家編號
public static Integer in=0; //記錄拿左筷子的個數
public Canzhuo4(int i) {
mem=i;
}
public void run() {
while(true){
int r=(mem+5-1)%5; //右筷子下標
int l=mem%5; //左筷子下標
synchronized(in) { //將拿左筷子的人數鎖住
if(in>=4) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
continue;
}
in++;
}
synchronized(a[l]) { //鎖住左筷子
System.out.println(Thread.currentThread().getName()+"拿起左筷子"+l);
System.out.println(in);
synchronized(a[r]) {
System.out.println(Thread.currentThread().getName()+"拿起右筷子"+r);
System.out.println(Thread.currentThread().getName()+"正在喫飯");
try {
Thread.sleep(100); //模擬哲學家喫飯
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"喫完了,開始思考");
in--;
}//a[r]
}//a[l]
}//_while
}
}
public class Test3 {
public static void main(String[] args) {
Canzhuo4 a1=new Canzhuo4(1);
Canzhuo4 a2=new Canzhuo4(2);
Canzhuo4 a3=new Canzhuo4(3);
Canzhuo4 a4=new Canzhuo4(4);
Canzhuo4 a5=new Canzhuo4(5);
new Thread(a1,"哲學家1").start();
new Thread(a2,"哲學家2").start();
new Thread(a3,"哲學家3").start();
new Thread(a4,"哲學家4").start();
new Thread(a5,"哲學家5").start();
}
}