I want to solve dining philosophers problem using java semaphores but I'm stuck. Highest id chopstick should be available but it seems to be always taken and i don't know why. Can anyone tell me where I made mistake?
Fork class:
class Fork {
public static Semaphore fork = new Semaphore(1);
public int id;
Fork(int id) {
this.id = id;
}
public int getId() {
return id;
}
public boolean take() {
return fork.tryAcquire();
}
public void putDown() {
fork.release();
}}
Philosopher class:
class Philosopher extends Thread {
private Fork fork_low;
private Fork fork_high;
private String name;
Philosopher(Fork fork_low, Fork fork_high, String name) {
this.fork_low = fork_low;
this.fork_high = fork_high;
this.name = name;
}
public void run() {
try {
sleep(1000);
} catch (InterruptedException ex) {
}
while (true) {
eat();
}
}
private void eat(){
if(fork_low.take()){
if(fork_high.take()){
try {
sleep(2000); // eating;
} catch (InterruptedException ex) { }
fork_high.putDown();
fork_low.putDown();
}
else{
fork_low.putDown();
}
}
}}
Main:
public static void main(String[] args) {
String[] names = {"Plato", "Aristotle", "Cicero", "Confucius", "Eratosthenes"};
Fork[] fork = new Fork[5];
Philosopher[] philosopher = new Philosopher[5];
for (int i = 0; i < fork.length; i++) {
fork[i] = new Fork(i);
}
for (int i = 0; i < philosopher.length; i++) {
if (i != philosopher.length - 1) {
philosopher[i] = new Philosopher(fork[i], fork[i+1], names[i]);
philosopher[i].start();
} else {
philosopher[i] = new Philosopher(fork[0], fork[i], names[i]);
philosopher[i].start();
}
}
}
You have a deadlock, because the Semaphore is static in the Fork class, which is equivalent to only have one fork available. It works perfectly when you make the Semaphore not static (2 random philosophers running on the same time).
You can observe your threads working in JDK's build in tool jvisualvm.