当前位置: 首页 > 知识库问答 >
问题:

Java用餐哲学家监视器

薛宏壮
2023-03-14

我的Java代码中有一个问题,它应该模拟pholosophers问题,如下所述:http://en.wikipedia.org/wiki/Dining_philosophers_problem我想输出所有哲学家的当前状态,每次他们中的一个吃饭或思考。输出应该是这样的:“OxOx(2)”,其中“X”表示哲学家在吃,“O”表示他在思考,“O”表示他在等筷子。括号中的数字表示状态已更改的哲学家的编号。我遇到的问题是,只有哲学家1和3(有时是2和4)吃东西,而其他人总是思考或等待叉子,并且不断重复,因此输出如下:

O X O(2)

o X o X o(4)

o X o(2)

o(4)

o X 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中的哲学家就餐有很多问题,但它们似乎都没有帮助,我的代码也有点不同。谢谢

共有1个答案

孙自怡
2023-03-14

我对它做了很多修改,终于可以工作了。代码是:

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();
    }
}
 类似资料:
  • 今天,我决定尝试解决哲学家吃饭的问题。所以我写下面的代码。但我认为这是不正确的,所以如果有人告诉我这是怎么回事,我会很高兴的。我使用fork作为锁(我只读取它们,因为我不把对它们的访问放在同步块中),我有一个扩展线程的类,它保留了它的两个锁。 我认为有些不对劲,因为第五位哲学家从不吃饭,第四位和第三位哲学家大多吃饭。提前感谢。

  • 本文向大家介绍餐饮哲学家问题(DPP),包括了餐饮哲学家问题(DPP)的使用技巧和注意事项,需要的朋友参考一下 餐饮哲学家的问题指出,有5位哲学家共享一张圆桌,他们交替吃饭和思考。每个哲学家都有一碗饭和5根筷子。哲学家需要左右筷子才能吃饭。饿了的哲学家只有在两把筷子都齐备的情况下才可以吃东西,否则哲学家放下筷子,重新开始思考。 餐饮哲学家是一个经典的同步问题,因为它演示了一大类并发控制问题。 餐饮

  • 我想用java信号量解决用餐哲学家的问题,但我被卡住了。最高ID的筷子应该是可用的,但它似乎总是采取,我不知道为什么。谁能告诉我我错在哪里了? Fork类: 哲学家班: 主要内容:

  • 我必须用信号量来解决这个问题。在我的代码中,每一个哲学家都在拿一根筷子,其他人都在等待。 我在主函数中仍然有一些错误。你能告诉我怎么使用筷子吗?我是BACI的初学者。

  • 根据这篇维基百科文章中的钱迪/米斯拉部分,我们有5位哲学家,编号为P1-P5。 根据这句话: 对于每一对争夺资源的哲学家,创建一个叉子,并将其交给具有较低ID的哲学家(n代表代理Pn)。每个叉子可以是脏的或干净的。最初所有的叉子都是脏的 当一个有叉子的哲学家收到一个请求消息时,如果叉子是干净的,他会保留它,但是如果叉子是脏的,他会放弃它。如果他把叉子送过去,他会先把叉子清理干净。 因此,如果知道所

  • 我们有一个任务来说明这个问题的僵局。我们已经编写了所有代码,并且代码可以编译,但是当运行代码时,一位哲学家最终吃了东西。所以这不意味着死锁实际上不会发生吗? 这就是输出:输出