2013-11-25 10 views
0

Silberschatz의 솔루션을 기반으로 Dining Philosopher 문제에 대한 모니터를 구현할 때 스레드 인터리빙 된 실행이 수행되지 않은 것처럼 보입니다. 부적절한 것을 차단 했습니까? 하드웨어 문제입니까? 왜냐하면 이제 모든 철학자들이 올바른 순서로 먹기 때문입니다.Dining 철학자가 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

이제는 작동하지만, wait() (및 동시성 패키지의 일부 클래스) 대신 Condition.await()을 사용하면 동기화 된 블록으로 인해 교착 상태가 발생합니다. 이것은 Wait/Notify (All)로 모니터를 구현하는 것이 불가능하다는 것을 의미합니까? – Matthias