Сегодня я решаю попытаться решить проблему обеденных философов. Поэтому я пишу код ниже. Но я думаю, что это неверно, поэтому я буду рад, если кто-то скажет мне, что с ним не так. Я использую forks для блокировок (я их только читаю, из-за этого я не добавляю к ним доступ в синхронизированных блоках), у меня есть класс, который расширяет поток, и он сохраняет свои два замка.Обеденные философы в java
import java.util.Random;
public class EatingPhilosophersProblem {
private final static Random RANDOM = new Random();
/**
*
* @author Damyan Class represents eating of every philosopher. It
* represents infinity cycle of eating.
*/
private static class PhilosopherEating extends Thread {
int forkOne;
int forkTwo;
public PhilosopherEating(String name, int forkOne, int forkTwo) {
super(name);
this.forkOne = forkOne;
this.forkTwo = forkTwo;
}
@Override
public void run() {
super.run();
while (true) {
requireLock(this, forkOne, forkTwo);
}
}
}
private static Boolean[] forks = new Boolean[] { new Boolean(true), new Boolean(true), new Boolean(true),
new Boolean(true), new Boolean(true) };
// locks should be created by new, otherwise almost 100% sure that they will
// point to the same object (because of java pools)
// this pools are used from java for immutable objects
private static void requireLock(PhilosopherEating philosopherEating, int firstIndex, int secondIndex) {
// we lock always from the the lower index to the higher, otherwise
// every philosopher can take his left fork and deadlock will apear
if (firstIndex > secondIndex) {
int temp = firstIndex;
firstIndex = secondIndex;
secondIndex = temp;
}
if (firstIndex == 4 || secondIndex == 4) {
System.err.println(firstIndex + " and " + secondIndex);
}
synchronized (forks[firstIndex]) {
synchronized (forks[secondIndex]) {
printPhilosopherhAction(philosopherEating, "start eating");
try {
Thread.sleep(RANDOM.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
printPhilosopherhAction(philosopherEating, "stop eating");
}
}
};
private static void printPhilosopherhAction(PhilosopherEating philosopherEating, String action) {
System.out.println("Philosopher " + philosopherEating.getName() + " " + action);
}
public static void main(String[] args) {
PhilosopherEating first = new PhilosopherEating("1 - first", 0, 1);
PhilosopherEating second = new PhilosopherEating("2 - second", 1, 2);
PhilosopherEating third = new PhilosopherEating("3 - third", 2, 3);
PhilosopherEating fourth = new PhilosopherEating("4 - fourth", 3, 4);
PhilosopherEating fifth = new PhilosopherEating("5 - fifth", 4, 0);
first.start();
second.start();
third.start();
fourth.start();
fifth.start();
}
Я думаю, что что-то не так, потому что пятый философ никогда не ест, в основном, четвертые и третьи философы едят. Спасибо заранее.
Большое спасибо. Вы правы, речь идет не о правильной синхронизации. Я знаю, что такое голод, но я никогда не видел такого сильного выражения голода. Спасибо! – DPM