进程同步互斥——不死锁的哲学家问题

一、需求分析

(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后运行

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值