/**
* 在1965年,Dijkstra提出并解决了一个他称之为哲学家进餐的同步问题。从那时起,每个发明新的同步原语的人都希望通过解决哲学家进餐间题来展示其同步原语的精妙之处。这个问题可以简单地描述:五个哲学家围坐在一张圆桌周围,每个哲学家面前都有一碟通心面,由于面条很滑,所以要两把叉子才能夹住。相邻两个碟子之间有一把叉子。
* 哲学家的生活包括两种活动:即吃饭和思考。当一个哲学家觉得饿时,他就试图去取他左边和右边的叉子。如果成功地获得两把叉子,他就开始吃饭,吃完以后放下叉子继续思考。
* 要保证哲学家不能饿死,就是就餐数一直为0;不能出现死锁和活锁.
* @author lijianji
*
*/
public class Test2 {
public static void main(String[] args) {
Fork aFork=new Fork("a");
Fork bFork=new Fork("b");
Fork cFork=new Fork("c");
Fork dFork=new Fork("d");
Fork eFork=new Fork("e");
Scientist scientistA=new Scientist("A",eFork,aFork);
Scientist scientistB=new Scientist("B",aFork,bFork);
Scientist scientistC=new Scientist("C",bFork,cFork);
Scientist scientistD=new Scientist("D",cFork,dFork);
Scientist scientistE=new Scientist("E",dFork,eFork);
new Thread(scientistA).start();
new Thread(scientistC).start();
new Thread(scientistB).start();
new Thread(scientistE).start();
new Thread(scientistD).start();
}
}
/**
* 科学家
* @author lijianji
*
*/
class Scientist implements Runnable{
private String name;
/**
* 左餐叉
*/
private Fork leftFork;
/**
* 右餐叉
*/
private Fork rightFork;
/**
* 就餐次数
*/
private int counts=0;
public Scientist(String name,Fork leftFork, Fork rightFork){
this.name=name;
this.leftFork=leftFork;
this.rightFork=rightFork;
}
@Override
public void run() {
//随机开始就餐或思考
int k=(int)Math.random()*10;
if(k%2==0){
this.dining();
}else{
this.thinking();
}
}
/**
* 进餐
*/
private void dining(){
try {
synchronized (leftFork) {
synchronized (rightFork) {
counts++;
System.out.println(name + ",开始进餐" + ", 用餐次数:" + counts
+ ", leftFork:" + leftFork.getName()
+ ", rightFork:" + rightFork.getName());
for (int i = 0; i < 10; i++) {
// System.out.println("\t\t\t\t "+name+":用餐时间:"+i);
Thread.sleep(100);
}
}
}
this.thinking();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 思考
*/
private void thinking(){
try {
Thread.sleep(2000);
// System.out.println(name+":思考 完2s,开始抢餐叉");
this.dining();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 餐叉
* @author lijianji
*
*/
class Fork{
private String name;
public Fork(String name){
this.name=name;
}
public String getName(){
return name;
}
}
java 多线程实现 哲学家进餐问题
于 2016-02-13 19:10:40 首次发布