餐饮哲学家问题中的饥饿
Posted
技术标签:
【中文标题】餐饮哲学家问题中的饥饿【英文标题】:Starvation in the dining philosopher problem 【发布时间】:2019-02-07 22:47:58 【问题描述】:我一直在 wikipedia 上寻找哲学家就餐问题的解决方案。 The resource hierarchy solution
我了解它的工作原理以及打破循环结构如何防止死锁,但解决方案如何防止饥饿?一个或几个线程不能继续运行,而一些线程无法取得进展吗?
如果没有,是什么阻止了这种情况的发生?
实现:
public class DinningphilMain
public static void main(String[] args) throws InterruptedException
int numPhil = 3;
Philosopher[] phil = new Philosopher[numPhil];
Fork[] forkArr=new Fork[numPhil];
for (int i = 0; i < numPhil; i ++)
forkArr[i]= new Fork(i);
for (int i = 0; i < numPhil-1; i++)
phil[i]=new Philosopher(i, forkArr[i], forkArr[i+1]);
phil[numPhil-1]= new Philosopher(numPhil-1, forkArr[0], forkArr[numPhil-1]);
for (Philosopher p : phil)
new Thread(p).start();
这是哲学家课
import java.util.Random;
public class Philosopher implements Runnable
int sleep = 1000;
int id;
int eatTime= 500;
Random rand = new Random();
Fork left;
Fork right;
public Philosopher(int id, Fork left, Fork right)
this.id = id;
this.left = left;
this.right = right;
private void think()
System.out.println("Philosopher " + id + " is thinking");
try
int thinkingTime = rand.nextInt(sleep);
Thread.sleep(thinkingTime);
catch (InterruptedException e)
e.printStackTrace();
private void getForks()
System.out.println("Philosopher " + id + " is picking up forks");
try
left.get();
right.get();
System.out.println("Philosopher " + id + " has both forks");
catch (InterruptedException e)
e.printStackTrace();
private void releaseForks()
System.out.println("Philosopher " + id + " is putting down forks");
left.release();
right.release();
private void eat()
System.out.println("Philosopher " + id + " is eating");
try
Thread.sleep(eatTime);
catch (InterruptedException e)
e.printStackTrace();
@Override
public void run()
while (true)
getForks();
eat();
releaseForks();
think();
这是分叉类
public class Fork
private int id;
private Thread thread;
public Fork(int id)
this.id = id;
thread = null;
public int getId()
return id;
public synchronized void get() throws InterruptedException
if (thread != null)
this.wait();
thread = Thread.currentThread();
public synchronized void release()
if (thread == Thread.currentThread())
thread = null;
this.notify();
【问题讨论】:
【参考方案1】:资源层次解决方案解决了死锁,但不能解决饥饿问题。
为了防止饥饿,您需要:
来自线程系统的保证,线程将被解除阻塞 监视器和条件变量的顺序相同 被屏蔽了。
自己做。换句话说,你必须保证没有 哲学家可能会饿死。例如,假设您维护一个队列 哲学家。当哲学家饿了时,他/她会被放到 队列的尾部。哲学家只有在他/她处于领先地位时才能吃东西 排长队,筷子是否空闲。
这取自C560 Lecture notes -- Dining Philosophers
【讨论】:
我的困惑来自于当我在 Java 中实现解决方案时,哲学家似乎按顺序进食(1 然后 2 然后 3...),而且似乎没有饥饿。我正在使用 wait() 和 notify() 来访问分叉,但我很确定 Java 中的这些方法不能保证顺序,所以看起来很奇怪 你能分享你的实现吗? 我已经用实现编辑了帖子。我认为可能是 Thread.sleep() 调用确保没有线程占用所有分叉【参考方案2】:简短的回答是它没有。哲学家进餐问题用于讨论并发问题;它本身并不是任何事情的单一解决方案(因此它被称为问题)。
餐饮哲学家的***页面本身显示了一些实现。第一个展示了一个糟糕的解决方案实施将如何导致饥饿。
https://en.wikipedia.org/wiki/Dining_philosophers_problem
【讨论】:
以上是关于餐饮哲学家问题中的饥饿的主要内容,如果未能解决你的问题,请参考以下文章