2013-11-25 80 views
0

當基於Silberschatz的解決方案爲餐飲哲學家問題實現監控時,似乎沒有線程交錯執行。我是否阻止了某些不合適的內容或者是否存在某些硬件問題?因爲現在所有的哲學家都只是按照正確的順序吃東西。餐飲哲學家在Java中監控方法:沒有交錯線程執行

public class DiningPhilosophersMonitor { 

public static final int NB_OF_PHILOSOPHERS = 5; 

private enum State {THINKING, HUNGRY, EATING} 
private State[] states = new State[NB_OF_PHILOSOPHERS]; 
private Object[] self = new Object[NB_OF_PHILOSOPHERS]; 

public DiningPhilosophersMonitor() { 

    for (int i=0; i<NB_OF_PHILOSOPHERS; i++) { 
     this.states[i] = State.THINKING; 
     System.out.println("Philosopher " + i + " is " + "THINKING"); 
     this.self[i] = new Object(); 
    } 
} 

public synchronized void takeForks(int i) { 
    this.states[i] = State.HUNGRY; 
    System.out.println("Philosopher " + i + " is " + "HUNGRY"); 

    test(i); 

    if (this.states[i] != State.EATING) { 
     try { 
      System.out.println("Philosopher " + i + " is " + "WAITING"); 

      synchronized (this.self[i]) { 
       this.self[i].wait(); 
      } 

     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public synchronized void returnForks(int i) { 
    this.states[i] = State.THINKING; 
    System.out.println("Philosopher " + i + " is " + "THINKING"); 

    test((i+NB_OF_PHILOSOPHERS-1) % NB_OF_PHILOSOPHERS); 
    test((i+1) % NB_OF_PHILOSOPHERS); 
} 

private void test(int i) { 
    if (
      this.states[(i+NB_OF_PHILOSOPHERS-1) % NB_OF_PHILOSOPHERS] != State.EATING && 
      this.states[i] == State.HUNGRY && 
      this.states[(i+1) % NB_OF_PHILOSOPHERS] != State.EATING 
     ) { 

     this.states[i] = State.EATING; 
     System.out.println("Philosopher " + i + " is " + "EATING"); 

     synchronized (this.self[i]) { 
      this.self[i].notifyAll(); 
     } 
    } 
} 
} 

public class Philosopher implements Runnable { 

private DiningPhilosophersMonitor monitor; 
private int i; 

public Philosopher(DiningPhilosophersMonitor monitor, int i) { 
    this.monitor = monitor; 
    this.i = i; 
} 

@Override 
public void run() { 
    for (int j=0; j<10; j++) { 

     monitor.takeForks(i); 

     SleepUtilities.nap(); 

     monitor.returnForks(i); 
    } 
} 
} 

public class Init { 

public static void main(String[] args) { 
    DiningPhilosophersMonitor monitor = new DiningPhilosophersMonitor(); 
    for (int i=0; i<DiningPhilosophersMonitor.NB_OF_PHILOSOPHERS; i++) { 
     new Thread(new Philosopher(monitor, i)).run(); 
    } 
} 
} 

public class SleepUtilities 
{ 
public static void nap() { 
    nap(NAP_TIME); 
} 

public static void nap(int duration) { 
     int sleeptime = (int) (NAP_TIME * Math.random()); 
     try { Thread.sleep(sleeptime*1000); } 
     catch (InterruptedException e) {} 
} 

private static final int NAP_TIME = 5; 
} 

回答

1

您需要調用線程的start()方法。如果你調用run(),它將由調用線程執行。

因此,與

new Thread(new Philosopher(monitor, i)).start(); 
+0

感謝您的快速支持更換

new Thread(new Philosopher(monitor, i)).run(); 

,這確實是一個愚蠢的錯誤。 – Matthias

+0

現在它可以工作,但如果我使用Condition.await()而不是wait()(以及來自併發包的某些類),則會因同步塊中的同步而導致死鎖。這是否意味着僅僅使用Wait/Notify(全部)來實現顯示器是不可能的? – Matthias