2013-01-13 27 views
-1

我做了一個簡單的圖形用戶界面,有5個表和叉,並試圖可視化這個着名的問題,但我無法實現完全實現。我沒有得到我的代碼的卡住點,如果有人有我的建議來解決這個問題,任何幫助將不勝感激,並提前致謝! 額外注:另外還有一點我想這是我的數組創建的想法的錯誤,我有一個錯誤java.lang.ArrayIndexOutOfBoundsException:5餐飲哲學家的線程和信號量

public class Philosopher implements Runnable { 


    private static Table table; 
    private int ID; 
    private int N = 5; 
    private static Semaphore s1 = new Semaphore(1) ; 
    private static Semaphore[] sarray = new Semaphore[5]; 
    private int[] array = new int[5]; 
    private int thinking = 0; 
    private int hungry = 1; 
    private int eating = 2; 
    private int left = (ID + N - 1) % N; 
    private int right = (ID + 1) % N; 

    void test(int i) 
    { 
     if((array[i] == hungry) && (array[left] != eating) && (array[right] != eating)) 
     { 
      table.ForkTake_GUI(i); 
      array[i] = eating; 
      sarray[i].release(); 

     } 
    } 

    void take_forks(int i) 
    { 
     try { 
      s1.acquire(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     array[i] = hungry; 
     table.Hungry_GUI(i); 
     test(i); 
     s1.release(); 
     table.Eating_GUI(i); 
     sarray[i].release(); 
    } 

    void put_forks(int i) 
    { 
     table.StopEating_GUI(i); 
     try { 
      s1.acquire(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     array[i] = thinking; 
     test(left); 
     test(right); 
     table.ForkPut_GUI(i); 
     s1.release(); 

    } 

    public Philosopher(int i) 
    { 
     setID(i); 
    } 

    public void run() 
    { 
     while(true) 
     { 
      Random RandomGenerator = new Random(); 
      int randomNum = RandomGenerator.nextInt(10); 
      try { 
       Thread.sleep((randomNum * 1000)); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


      take_forks(ID); 
      //table.Eating_GUI(); 
      put_forks(ID);  
     } 

    } 

    public static void main(String args[]) { 

     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        table = new Table(); 
        table.frame.setVisible(true); 
       } 
       catch(Exception e){ 
        e.printStackTrace(); 
       } 

      } 
     }); 

     Philosopher p1 = new Philosopher(1); 
     Philosopher p2 = new Philosopher(2); 
     Philosopher p3 = new Philosopher(3); 
     Philosopher p4 = new Philosopher(4); 
     Philosopher p5 = new Philosopher(5); 
     Thread pt1 = new Thread(p1); 
     Thread pt2 = new Thread(p2); 
     Thread pt3 = new Thread(p3); 
     Thread pt4 = new Thread(p4); 
     Thread pt5 = new Thread(p5); 

     sarray[0] = new Semaphore(1); 
     sarray[1] = new Semaphore(1); 
     sarray[2] = new Semaphore(1); 
     sarray[3] = new Semaphore(1); 
     sarray[4] = new Semaphore(1); 

     pt1.start(); 
     pt2.start(); 
     pt3.start(); 
     pt4.start(); 
     pt5.start(); 

    } 
    public int getID() { 
     return ID; 
    } 
    public void setID(int iD) { 
     ID = iD; 
    } 

} 
+0

*「我沒有得到我的代碼卡住的點」*如果你沒有卡住,你爲什麼在這裏? *「如果有人有我的建議來解決這個問題」*我仍然不知道你的問題是什麼。 –

+0

我不知道爲什麼我的代碼運行正常,這是我的卡住點,我卡住了某處,但我不知道,這是我試圖解釋並告訴 – user1902018

+0

你不明白什麼?這看起來像正確的解決方案(安全,無飢餓),但只有一個哲學家可以一次吃東西。 – zch

回答

1

看看,你獲得從互斥 - 點是你不這樣做,所以至少在那裏有冗餘的代碼。

其它注意事項:

  • 你定義N種,但全國各地使用的幻數5。
  • 您似乎有一個「中央」互斥體,每個叉體都有一個互斥體。使用中央互斥體已經可以解決原始問題。
  • 考慮將每個互斥鎖及其保護的數據放入一個聚合中。這將清楚表明,這五個互斥體是爲五個叉而不是五個哲學家的,或者?
  • 您的越界顯然是由1基指數和0指數之間的轉換引起的。計算左右後,可能是由更改ID引起的?一般來說,我不會將它們存儲爲成員。另外,請注意,您擁有的價值觀是哲學家的價值觀,而不是叉子的價值觀!畫一張照片,這將有助於你正確地獲得這些照片!