3

我的Java代碼中有一個問題應該模擬用餐者pholosophers問題,這裏描述如下:http://en.wikipedia.org/wiki/Dining_philosophers_problem 我想輸出當前所有哲學家的狀態,每次他們吃飯或認爲。輸出應該是這樣的: 「O X O o X(2)」,其中「X」表示哲學家吃,「O」表示他在思考,「o」表示他在等待筷子。括號中的數字表示狀態已經改變的哲學家的數量。我有的問題是,只有哲學家1和3(有時是2和4)吃,而其他人總是思考或等待叉,並不斷重複,所以輸出看起來像這樣:爪哇就餐哲學家監視器

OXOOO(2)

○×○XO(4)

O O O X O(2)

○○○○○(4)

○×○○○(2)

o X o X o (4)

O O O X O(2)

...

完整的代碼是在這裏:

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

class Stick{ 
    boolean available; 
    public Stick(){ 
     available = true; 
    } 
    public void setAvailability(boolean flag){ 
     this.available = flag; 
    } 
    public boolean getAvailability(){ 
     return available; 
    } 
} 

class Philosopher extends Thread{ 
    private int id; 
    private Stick l, r; 
    private Lock monitor; 
    private Condition[] cond; 
    private Problem p; 

    private void outputState(int _id){ 
     StringBuffer sb = new StringBuffer(); 
     for(int i=0; i<5; i++) 
      sb.append(p.getState(i) + " "); 
     System.out.println(sb + "(" + (_id+1) + ")"); 
    } 

    private void takeChopSticks(int _id) throws InterruptedException{ 
     monitor.lock(); 
     try{ 
      p.setState(_id, "o"); 
      while(!l.getAvailability() || !r.getAvailability()){ 
       cond[_id].await(); 
      } 
      l.setAvailability(false); 
      r.setAvailability(false); 
      p.setState(_id, "X"); 
      outputState(_id); 
     }finally{ 
      monitor.unlock(); 
     } 
    } 

    private void eat() throws InterruptedException{ 
     Thread.sleep(1000); 
    } 

    private void think(int _id) throws InterruptedException{ 
     Thread.sleep(2000); 
    } 

    public void run(){ 
     while(true){    
      try{ 
       takeChopSticks(this.id); 
       eat(); 
       releaseChopSticks(this.id); 
       think(this.id); 
      }catch(InterruptedException e){System.out.println("srusila se metoda run()");} 

     } 
    } 

    private void releaseChopSticks(int _id) throws InterruptedException{ 
     monitor.lock(); 
     try{ 
      l.setAvailability(true); 
      r.setAvailability(true); 
      cond[_id].signalAll(); 
      cond[(_id+4)%5].signalAll(); 
      p.setState(_id, "O"); 
      outputState(_id); 
     }finally{ 
      monitor.unlock(); 
     } 
    } 

    public Philosopher(Problem _p, int _id, Stick _l, Stick _r, Lock m){ 
     cond = new Condition[5]; 
     monitor = m; 
     id = _id; 
     l = _l; 
     r = _r; 
     p = _p; 
     for(int i=0; i<5; i++) 
      cond[i] = monitor.newCondition(); 
    } 
} 

public class Problem { 
    Thread[] t; 
    Stick[] s; 
    private enum State {O, X, o}; 
    private State[] state; 

    public State getState(int id){ 
     return state[id]; 
    } 

    public void setState(int id, String s){ 
     if(s == "o") 
      state[id] = State.o; 
     else if(s=="O") 
      state[id] = State.O; 
     else if(s=="X") 
      state[id] = State.X; 
    } 

    public Problem(){ 
     state = new State[5]; 
     t = new Thread[5]; 
     s = new Stick[5]; 
     for(int i=0; i<5; i++){ 
      s[i] = new Stick(); 
      state[i] = State.O; 
     } 
     Lock m = new ReentrantLock(); 
     for(int i=0; i<5; i++) 
      t[i] = new Philosopher(this, i, s[i], s[(i+4)%5], m); 
     for(int i=0; i<5; i++) 
      t[i].start(); 

    } 

    public static void main(String[] args){ 
     new Problem(); 
    } 
} 

我知道有關於Java中哲學家進餐媒體鏈接的幾個問題,但他們似乎都沒有幫助,而且我的代碼有點不同。謝謝。

+0

你'Stick'類似乎需要''上可變available'感謝 – hoaz

+0

關鍵字volatile',但沒有工作:( – dmacan23

回答

0

我已經修改了很多,它終於有效。 的代碼是:

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

class Chopstick{ 
    private boolean availability; 

    public Chopstick(){ 
     availability = true; 
    } 

    public boolean getAvailability(){ 
     return availability; 
    } 

    public void setAvailability(boolean flag){ 
     availability = flag; 
    } 
} 

class Helper{ 
    private Lock mutex = null; 
    private Condition[] cond; 
    private String[] state; 
    private int[] id; 

    private void outputState(int id){ 
     StringBuffer line = new StringBuffer(); 
     for(int i=0; i<5; i++) 
      line.append(state[i] + " "); 
     System.out.println(line + "(" + (id+1) + ")"); 
    } 

    public Helper(){ 
     id = new int[5]; 
     mutex = new ReentrantLock(); 
     state = new String[5]; 
     cond = new Condition[5]; 
     for(int i=0; i<5; i++){ 
      id[i] = i; 
      state[i] = "O"; 
      cond[i] = mutex.newCondition(); 
     } 
    } 

    public void setState(int id, String s){ 
     state[id] = s; 
    } 

    public void grabChopsticks(int id, Chopstick l, Chopstick r){ 
     mutex.lock(); 
     try{ 
      setState(id, "o"); 
      while(!l.getAvailability() || !r.getAvailability()) 
       cond[id].await(); 

      l.setAvailability(false); 
      r.setAvailability(false); 
      setState(id, "X"); 
      outputState(id); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     }finally{ 
      mutex.unlock(); 
     } 
    } 


    public void releaseChopsticks(int id, Chopstick l, Chopstick r){ 
     mutex.lock(); 
     try{ 
      setState(id, "O"); 
      l.setAvailability(true); 
      r.setAvailability(true); 
      cond[(id+1)%5].signalAll(); 
      cond[(id+4)%5].signalAll(); 
      outputState(id); 
     }finally{ 
      mutex.unlock(); 
     } 
    } 
} 


class Philosopher implements Runnable{ 
    private Helper hlp; 
    private Chopstick l, r; 
    private int id; 
    public Philosopher(int id, Chopstick l, Chopstick r, Helper i){ 
     this.hlp = i; 
     this.l = l; 
     this.r = r; 
     this.id = id; 
    } 

    private void eat(){ 
     try{ 
      Thread.sleep(2000); 
     }catch(InterruptedException e){} 
    } 

    private void think(){ 
     try{ 
      Thread.sleep(2000); 
     }catch(InterruptedException e){} 
    } 

    public void run(){ 
     while(true){ 
      hlp.grabChopsticks(id, l, r); 
      eat(); 
      hlp.releaseChopsticks(id, l, r); 
      think(); 
     } 
    } 
} 

public class Problem { 
    private Chopstick[] s; 
    private Philosopher[] f; 
    private Helper hlp; 

    private void init(){ 
     s = new Chopstick[5]; 
     f = new Philosopher[5]; 
     hlp = new Helper(); 
     for(int i=0; i<5; i++) 
      s[i] = new Chopstick(); 

     for(int i=0; i<5; i++){ 
      f[i] = new Philosopher(i, s[i], s[(i+4)%5], hlp); 
      new Thread(f[i]).start(); 
     } 

    } 

    public Problem(){ 
     init(); 
    } 

    public static void main(String[] args){ 
     new Problem(); 
    } 
} 
+0

因爲'的mutex'它看起來像只有1哲學家可以在任何時候開始攫取? –