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();
}
}