一、需求分析
(1)一张圆桌上有一大碗面,5个盘子,每位哲学家一个,还有五把叉子。每位想吃饭的哲学家将坐到桌子旁分配给他的位置上,使用盘子两侧的叉子,取面和吃面。问题是:设计一套礼仪(算法)以允许哲学家吃饭。算法必须保证互斥(没有两位哲学家同时使用同一把叉子),同时还要避免死锁和饥饿。
(2)本程序的运行基本上不输入数据,自行运行。
(3)结果的输出形式可以是动态的动画或是表格,用于显示哲学家的动态。
二、概要设计
1.采用数组来表示叉子的使用情况,信号量来表示该哲学家的动态
2.本程序共7个模块(除了界面以及事件),分别如下:
1)思考模块 think()
2)等待进入房间模块 inwait()
3)就餐模块 eat()
4)判断叉子的使用情模块况 wait()
5)放下叉子模块 signal()
6)判断是否就餐模块 p()
7)主程序模块 jiucan()
3.主程序的流程图
4.模块之间的层次关系
三、详细设计
1.private int[] fork=new int[5]; //叉子的使用情况,0表示可以使用,1表示已被使用
2.思考模式:think()
private int think(int i){
textArea2.append("哲学家 "+i+" 在思考\n");
//jtext2.setText("哲学家 "+i+" 在思考\n");
//System.out.println("哲学家 "+i+" 在思考");
return -1;
}
3. 等待进入房间模块 inwait()
private int inwait(int i){
textArea4.append("哲学家 "+i+" 在等待进入房间\n");
//System.out.println("哲学家 "+i+" 在等待进入房间");
return 2;
}
4. 就餐模块eat()
private void eat(int i){
fork[i]=1;
fork[(i+1)%5]=1;
textArea1.append("哲学家 "+i+" 在就餐\n");
//System.out.println("哲学家 "+i+" 在就餐");
}
5.判断叉子的使用情模块况wait()
private int wait(int i){
if(i==1) return 1;
else return 0;
}
6.放下叉子模块 signal()
private void signal(int i){
fork[i]=0;
}
7.判断是否就餐模块p()
private int p(int i){
if((wait(fork[i])==0)){
if(wait(fork[(i+1)%5])==0){
eat(i);
return 0;
}
else {textArea3.append("哲学家"+i+"在等待第"+(i+1)%5+"把叉子\n");
//System.out.println("哲学家"+i+"在等待第"+(i+1)%5+"把叉子");
return 1;}
}
else {textArea3.append("哲学家 "+i+" 在等待第"+i+"把叉子\n");
//System.out.println("哲学家 "+i+" 在等待第"+i+"把叉子");
return 1;}
}
8.主程序模块jiucan()
private void jiucan(int num) {
int choice;
int choice1;
int i0,i1,i2,i3,i4,i;
i0=0;i1=0;i2=0;i3=0;i4=0;
while(num!=0){
//for(i=0;i<5;i++)
//System.out.println(fork[i]+" ");
//System.out.println();
textArea1.setText(" ");
textArea2.setText(" ");
textArea3.setText(" ");
textArea4.setText(" ");
System.out.println();
choice1=(int)(Math.random()*5);
//System.out.println(choice1);
if(choice1!=0){
if(i0==1) choice=0;
elsechoice=(int)(Math.random()*2);//0表示吃饭或等待,1表示思考
if(choice==0) i0=p(0);
else i0=think(0);
}
else i0=inwait(0);
if(choice1!=1){
if(i1==1) choice=0;
elsechoice=(int)(Math.random()*2);//0表示吃饭或等待,1表示思考
if(choice==0) i1=p(1);
else i1=think(1);
}
else i1=inwait(1);
if(choice1!=2){
if(i2==1) choice=0;
elsechoice=(int)(Math.random()*2);//0表示吃饭或等待,1表示思考
if(choice==0) i2=p(2);
else i2=think(2);
}
else i2=inwait(2);
if(choice1!=3){
if(i3==1) choice=0;
elsechoice=(int)(Math.random()*2);//0表示吃饭或等待,1表示思考
if(choice==0) i3=p(3);
else i3=think(3);
}
else i3=inwait(3);
if(choice1!=4){
if(i4==1) choice=0;
elsechoice=(int)(Math.random()*2);//0表示吃饭或等待,1表示思考
if(choice==0) i4=p(4);
else i4=think(4);
}
else i4=inwait(4);
signal(0);signal(1);signal(2);signal(3);signal(4);
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(Jiemian.class.getName()).log(Level.SEVERE, null, ex);
}
num--;
}
}
四、调试分析
1.关于无限运行之后无法停止以及无法关闭,暂时无法解决。
五、用户使用说明
本程序的功能是解决哲学家问题
程序开始要求用户输入需要运行的次数即哲学家就餐的回合数,或是选择无无限运行即无法停止,自动运行。在用户输入或是选择后,按相应的开始键就可以开始相应的运行。
请注意,在开始无限运行后无法在界面上关闭或是停止该程序,只能强行停止。
六、测试与运行结果
主界面
输入运行次数3后运行