Голод в столовой философской проблеме
Я искал решение проблемы столовой философии в Википедии. Решение по иерархии ресурсов
Я понимаю, как это работает и как нарушение круговой структуры предотвращает тупики, но как решение предотвращает голодание? Не может ли один или несколько потоков продолжать работу, в то время как некоторые не смогут добиться прогресса?
Если нет, что мешает этому случиться?
Реализация:
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();
}
}
2 ответа
Решение по иерархии ресурсов устраняет тупики, но не решает проблему голода.
Чтобы предотвратить голодание, вам нужно:
Гарантия от системы потоков, что потоки будут разблокированы от мониторов и переменных условий в том же порядке, в котором они заблокированы.
Чтобы сделать это самостоятельно. Другими словами, вы должны гарантировать, что ни один философ не может голодать. Например, предположим, вы поддерживаете очередь философов. Когда философ голоден, он / она попадает в хвост очереди. Философ может есть, только если он / она стоит во главе очереди и если палочки для еды свободны.
Это взято из конспекта лекций C560 - Философы ужина
Короткий ответ - это не так. Проблема столовых философов используется для обсуждения проблемы параллелизма; само по себе это не единственное решение для чего-либо (следовательно, почему это называется проблемой).
Страница википедии для самих столовых философов показывает несколько реализаций. Первый показывает, как плохая реализация решения вызовет голод.