我的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中哲學家進餐媒體鏈接的幾個問題,但他們似乎都沒有幫助,而且我的代碼有點不同。謝謝。
你'Stick'類似乎需要''上可變available'感謝 – hoaz
關鍵字volatile',但沒有工作:( – dmacan23