3

我的 Java 代码中有一个问题应该模拟餐饮哲学家问题,如下所述:http ://en.wikipedia.org/wiki/Dining_philosophers_problem 我想在其中一个人吃饭或吃饭时输出所有哲学家的当前状态认为。输出应该是这样的:“OXO o X (2)”,其中“X”表示哲学家在吃东西,“O”表示他在思考,“o”表示他在等筷子。括号中的数字表示状态发生变化的哲学家的数量。我遇到的问题是只有哲学家 1 和 3(有时是 2 和 4)吃东西,而其他人总是思考或等待分叉,并且不断重复,所以输出如下所示:

奥克斯 (2)

o X o XO (4)

o O o X o (2)

o O o O o (4)

o X o O o (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 中用餐哲学家的问题,但似乎没有一个有帮助,而且我的代码有点不同。谢谢。

4

1 回答 1

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();
    }
}
于 2013-05-15T23:23:11.263 回答