Java學習

          java,spring,structs,hibernate,jsf,ireport,jfreechart,jasperreport,tomcat,jboss -----本博客已經搬家了,新的地址是 http://www.javaly.cn 如果有對文章有任何疑問或者有任何不懂的地方,歡迎到www.javaly.cn (Java樂園)指出,我會盡力幫助解決。一起進步

           

          java解 哲學家就餐問題

          哲學家進餐問題是一個多線程運用的經典例子,涉及到線程同步/互斥,臨界區訪問問題以及一個避免死鎖的解決方法。

               有五個哲學家繞著圓桌坐,每個哲學家面前有一盤面,兩人之間有一支筷子,這樣每個哲學家左右各有一支筷子。

             哲學家有2個狀態,思考或者拿起筷子吃飯。如果哲學家拿到一只筷子,不能吃飯,直到拿到2只才能吃飯,并且一次只能拿起身邊的一支筷子。一旦拿起便不會放下筷子直到把飯吃完,此時才把這雙筷子放回原處。

             如果,很不幸地,每個哲學家拿起他或她左邊的筷子,那么就沒有人可以吃到飯了。這就會造成死鎖了。。這是需要堅決杜絕的,正如操作系統的死鎖問題。
                                                                                               
          代碼如下:
          import java.util.Random;
          public class DiningPhils
          {
          public static void main(String[] args)
          {
          int n = 10;
          if( n < 1)
          {
          System.err.println( "DiningPils <# of philosophers>" );
          System.exit(-1);
          }
          DiningPhils self = new DiningPhils();
          self.init(n);
          }

          public int getCount()
          {
          return n;
          }
          public void setChopstick( int i, boolean v)
          {
          chops[ i ] = v;
          }
          public boolean getChopstick( int i )
          {
          return chops[i];
          }

          private void init( final int N)
          {
          r = new Random();
          n = ( N < 0 || N > maxPhils ) ? maxPhils : N;
          chops = new boolean[n];
          phils = new Philosopher[n];
          initPhils();
          dumpStatus();
          }
          private void initPhils()
          {
          for( int i = 0; i< n; i++ )
          {
          phils[i] = new Philosopher( this, i );
          phils[i].setTimeSlice( generateTimeSlice());
          phils[i].setPriority( Thread.NORM_PRIORITY - 1);
          /**哲學家進程降低一級,使所有哲學家進程
          *全部初始化完畢前不會有哲學家進程搶占主線程*/
          }
          while( moreToStart() )
          {
          int i = Math.abs( r.nextInt()) % n;
          if( !phils[i].isAlive())
          {
          System.out.println( " ### Philosopher " +
          String.valueOf( i ) + " started.");
          phils[i].start();
          }
          }
          System.out.println( "\nPhilosophers Chopsticks"
          + "\n(1 = eating, 0 = thinking) (1 = taken, 0 = free)");
          }
          public int generateTimeSlice()
          {
          int ts = Math.abs(r.nextInt()) % (maxEat + 1);
          if( ts == 0 )
          ts = minEat;
          return ts;
          }
          public void dumpStatus()
          {
          for( int i = 0; i < n; i++)
          System.out.print(phils[i].getEat() ? 1 : 0);
          for( int i = n; i < maxPhils + 4; i++ )
          System.out.print(" ");
          for( int i = 0; i < n; i++)
          System.out.print(chops[i]? 1:0);
          System.out.println();
          }

          private boolean moreToStart()
          {
          for( int i = 0; i < phils.length; i++ )
          {
          if( !phils[i].isAlive())
          return true;
          }
          return false;
          }
          private int n;
          private Philosopher[] phils;
          private boolean[] chops;
          private Random r;
          private static final int maxPhils = 24; //最多哲學家數
          private static final int maxEat = 4; //最多進餐時間
          private static final int minEat = 1; //最少進餐時間
          }
          class Philosopher extends Thread
          {
          public Philosopher( DiningPhils HOST , int i )
          {
          host = HOST;
          index = i;
          }
          public void setTimeSlice( int TS )
          {
          ts = TS;
          }
          public void setLeftChopstick( boolean flag )
          {
          host.setChopstick(index, flag);
          }
          public void setRightChopstick( boolean flag )
          {
          host.setChopstick((index + 1)% host.getCount() , flag);
          }
          private void releaseChopsticks()
          {
          setLeftChopstick(false);
          setRightChopstick(false);
          }
          public boolean chopsticksFree()
          {
          return !host.getChopstick(index) &&
          !host.getChopstick((index+1)%host.getCount());
          }

          public void run()
          {
          while(true)
          {
          grabChopsticks();
          eat();
          think();
          }
          }
          private synchronized void grabChopsticks() /**臨界區函數,確保哲學家在沒有筷子或筷子不夠時思考,滿足條件后才就餐*/
          {
          while( !chopsticksFree())
          {
          try
          {
          wait();
          }
          catch( InterruptedException e){}
          }
          takeChopsticks();
          notifyAll();
          }
          private void takeChopsticks()
          {
          setLeftChopstick( true );
          setRightChopstick( true );
          setEat(true);
          host.dumpStatus();
          }
          private void eat()
          {
          pause();
          setEat( false );
          releaseChopsticks();
          }
          private void think()
          {
          pause();
          }
          private void pause()
          {
          setTimeSlice( host.generateTimeSlice());
          try
          {
          sleep(ts*1000);
          }
          catch( InterruptedException e){}
          }
          private void setEat(boolean v)
          {
          isEating = v;
          }
          public boolean getEat()
          {
          return isEating;
          }
          private DiningPhils host;
          private boolean isEating;
          private int index;
          private int ts;
          }

          posted on 2008-07-15 16:51 找個美女做老婆 閱讀(614) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          導航

          統計

          公告

          本blog已經搬到新家了, 新家:www.javaly.cn
           http://www.javaly.cn

          常用鏈接

          留言簿(6)

          隨筆檔案

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 靖宇县| 独山县| 吕梁市| 封丘县| 北宁市| 古蔺县| 论坛| 从江县| 阜新市| 高要市| 巧家县| 思南县| 玉门市| 白银市| 杭锦旗| 股票| 红桥区| 元谋县| 大英县| 广昌县| 涿鹿县| 夹江县| 高密市| 前郭尔| 曲水县| 通河县| 镇安县| 常山县| 时尚| 黄梅县| 沧源| 梁平县| 灵石县| 福安市| 榆中县| 花莲县| 烟台市| 卫辉市| 佛山市| 元朗区| 赞皇县|