java - Dining Philosophers 代码中发生的饥饿

标签 java multithreading concurrency

这是我对哲学家晚餐并发问题的实现。我只为两个线程工作,其余线程遭受饥饿,从字面上看 ;) 如果您能找到原因,我将不胜感激。

这是输出:

Philosopher 2 is eating
Philosopher 0 is eating
Philosopher 2 is eating
Philosopher 0 is eating
Philosopher 2 is eating
Philosopher 0 is eating
Philosopher 2 is eating
Philosopher 0 is eating
Philosopher 2 is eating
Philosopher 2 is eating
Philosopher 0 is eating
Philosopher 2 is eating
Philosopher 0 is eating

代码如下:

public class PhilosophersDinner {

    public static void main(String[] args) {
        Chopstick2[] chopsticks = new Chopstick2[5];
        Philosopher [] philosophers = new Philosopher[5];

        for (int i = 0; i < 5; i++) {
            Chopstick2 stick = new Chopstick2();
            chopsticks[i] = stick;
        }

        for (int i = 0; i < 5; i++) {
            Philosopher philo = new Philosopher(chopsticks[i] , chopsticks[(i+1)%5], i+"");
            philosophers[i] = philo;
        }

        for (int i = 0; i < philosophers.length; i++) {
            new Thread(philosophers[i]).start();
        }
    }

}

class Philosopher implements Runnable {

    private final Chopstick2 left;
    private final Chopstick2 right;
    private final String id;

    public Philosopher(Chopstick2 l, Chopstick2 r, String id){
        this.left = l;
        this.right = r;
        this.id = id;
    }

    public void eat(){
        if (left.pickUp()) {
            if (right.pickUp()) {
                chew();
                putDown();
            } else left.putDown();
        }
    }


    public void run(){
        for (int i = 0; i < 10; i++) {
            eat();
        }
    }

    public void chew(){
        try {
            System.out.println("Philosopher "+id+" is eating");
            Thread.sleep(400);
        } catch (InterruptedException e) {
            e.printStackTrace();
            // release lock here?
        } 
    }

    public void putDown(){
        left.putDown();
        right.putDown();
    }

}

class Chopstick2 {
    private volatile boolean taken = false;

    public synchronized boolean pickUp(){
        if (!taken) { 
            taken = true;
            return true;
        }
        else return false;
    }

    public synchronized void putDown(){
        taken = false;
    }
}

最佳答案

问题是前两个拿到筷子的哲学家花了半秒的时间吃饭,而在这段时间里,其他三个用餐者尝试吃饭,直到他们放弃并退出。

一个解决方案是让所有哲学家吃指定的时间,而不是尝试吃特定的次数。

    for (long i = System.currentTimeMillis()+10000; i > System.currentTimeMillis(); ) {
        eat();
    }

关于java - Dining Philosophers 代码中发生的饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17257018/

相关文章:

java - 为什么 JSON pretty-print 不起作用?

c# - 当其他线程开始执行某些工作时 Wpf 窗口卡住

c++ - 两个线程可以调用同一个 DLL 中的两个函数吗?

c++ - Visual C++ 2010 是否支持 C++11 线程库?

java - 如何从外部不相关的代码读取正在运行的 Swing GUI 的 TextField 或 Cell 值?

java - 如何正确处理并发?

具有持久资源的 Java 线程

java - 数组索引越界,使用多维数组作为游戏板

java - 我应该始终使用 Lambda 表达式进行异常测试吗?

java - 使 PrimeFaces 数据表默认可编辑