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