日期:2014-05-20  浏览次数:20735 次

Java实现哲学家进餐,线程调度出现问题,求指点!


package com.java.mythread;

/**
 * 哲学家进餐问题的解决
 * 缺点:线程调度不是先进先出调度或优先级调度
 * */
public class Dining {
public static void main(String[] args){
Chopstick[] chops = new Chopstick[5];
Philosopher[] philos= new Philosopher[5];
for(int i= 0;i<5;i++){
chops[i] = new Chopstick();
}
for(int i= 0;i<5;i++){
philos[i] = new Philosopher(i,chops[i],chops[(i+1)%5]);
}

for(int i= 0;i<5;i++){
philos[i].start();
}
}
}

class Chopstick{
private boolean available;
public Chopstick(){
available = true;
}
public void takeUp(){
available = false;
}
public void putDown(){
available = true;
}
public boolean getStatus(){
return available;
}
}

class Philosopher extends Thread{
public static int eatTime = 200, thinkTime = 300; 
private Chopstick left,right;
int philo_num;
public Philosopher(int No,Chopstick lc,Chopstick rc){
left = lc;
right = rc;
philo_num = No;
//setDaemon(true);
}
synchronized public void requestChops(){
while(!left.getStatus() || !right.getStatus()){
System.out.println("哲学家"+philo_num+"正在等待……");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
left.takeUp();
right.takeUp();
}
synchronized public void returnChops(){
left.putDown();
right.putDown();
notify();
}
public void eat(){
System.out.println("哲学家"+philo_num+"正在进餐……");
try{
sleep(eatTime);
}catch(Exception e){}
}
public void think(){
System.out.println("哲学家"+philo_num+"正在思考……");
try{
sleep(thinkTime);
}catch(Exception e){}
}
public void run(){
while(true){
this.think();
this.requestChops();
this.eat();
this.returnChops();
}
}
}

最后运行结果是:
哲学家0正在思考……
哲学家3正在思考……
哲学家2正在思考……
哲学家1正在思考……
哲学家4正在思考……
哲学家0正在等待……
哲学家4正在进餐……
哲学家3正在等待……
哲学家1正在等待……
哲学家2正在进餐……
哲学家4正在思考……
哲学家2正在思考……
哲学家4正在进餐……
哲学家2正在进餐……
无论等多长时间,只有哲学家2和哲学家4线程在运行,这掌握很费解啊。
代码中当某哲学家进餐完毕,执行this.returnChops();操作时,调用notify()函数后,不是所有等待进程同时竞争资源吗?为什么会只有两个线程一直运行,其他线程出于饥饿状态?改成notifyAll()函数,结果也一样。
哪位能给下指点啊?


















------解决方案--------------------
没格式化没着色真难看
Java code
package com.java.mythread;
/**
 * 哲学家进餐问题的解决
 * 缺点:线程调度不是先进先出调度或优先级调度
 * */
public class Dining {
public static void main(String[] args){
Chopstick[] chops = new Chopstick[5];
Philosopher[] philos= new Philosopher[5];
for(int i= 0;i<5;i++){
chops[i] = new Chopstick();
}
for(int i= 0;i<5;i++){
philos[i] = new Philosopher(i,chops[i],chops[(i+1)%5]);
}

for(int i= 0;i<5;i++){
philos[i].start();
}
}
}

class Chopstick{
private boolean available;
public Chopstick(){
available = true;
}
public void takeUp(){
available = false;
}
public void putDown(){
available = true;
}
public boolean getStatus(){
return available;
}
}

class Philosopher extends Thread{
public static int eatTime = 200, thinkTime = 300;  
private Chopstick left,right;
int philo_num;
public Philosopher(int No,Chopstick lc,Chopstick rc){
left = lc;
right = rc;
philo_num = No;
//setDaemon(true);
}
synchronized public void requestChops(){
while(!left.getStatus() || !right.getStatus()){
System.out.println("哲学家"+philo_num+"正在等待……");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
left.takeUp();
right.takeUp();
}
synchronized public void returnChops(){
left.putDown();
right.putDown();
notify();
}
public void eat(){
System.out.println("哲学家"+philo_num+"正在进餐……");
try{
sleep(eatTime);
}catch(Exception e){}
}
public void think(){
System.out.println("哲学家"+philo_num+"正在思考……");
try{
sleep(thinkTime);
}catch(Exception e){}
}
public void run(){
while(true){
this.think();
this.requestChops();
this.eat();
this.returnChops();
}
}
}