I am working on a Java project to simulate the dining philosophers problem.
I started with the basic behavior, where each thread think(), getForks(), eat(), and putForks(). So there's no prevention of deadlocks or starvation (done on purpose).
The getForks() method works like this:
getForks(){
while(forks[rightFork]==0) /*0 means fork is not on the table, so wait*/
print(Thread #id waiting for right fork);
forks[rightFork] = 0;
while(forks[leftFork]==0)
print(Thread #id waiting for left fork);
forks[leftFork = 0;
}
I put a sleep(5000) between getting the right and the left fork, so the program is running into a deadlock (with each thread holding the right fork). What is unexpected, however, is that for some reason execution is halting once it reaches the deadlock. I expected that the "Thread #id waiting for fork" messages would keep being printed during the deadlock, but they are not. Once deadlock is reached no more messages are printed.
Any clue why?
If you want to see the whole code, here it's:
public class Philosophers{
private static final int NUMBER = 3;
private static final int MIN_SLEEP = 1000;
private static final int MAX_SLEEP = 6000;
private static Thread[] threads = new Thread[NUMBER];
private static int[] forksArray = new int[8];
private static void start(){
System.out.println("Simulation started.");
//Initialize forks array (1 means on the table)
for(int i=0;i<7;i++)
forksArray[i] = 1;
//Create and start individual threads
for(int i=0;i<NUMBER;i++){
threads[i] = new Thread(new Philosopher(i));
threads[i].start();
}
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
start();
}
});
}
private static class Philosopher implements Runnable{
private int id;
private int leftFork;
private int rightFork;
public void run(){
System.out.println("Thread "+id+" started.");
while(true){
think();
getForks();
eat();
putForks();
}
}
public Philosopher(int id){
this.id = id;
this.rightFork = id;
if(id==NUMBER - 1)
this.leftFork = 0;
else
this.leftFork = id + 1;
}
public void think(){
System.out.println("Thread "+id+" thinking...");
try{
int sleepInterval = MIN_SLEEP + (int)(Math.random() * ((MAX_SLEEP - MIN_SLEEP) + 1));
Thread.sleep(sleepInterval);
}
catch(Exception e){
System.out.println(e);
}
}
public void getForks(){
System.out.println("Thread "+id+" getting forks.");
//Grab fork on the right
while(forksArray[rightFork]==0)
System.out.println("Thread "+id+" waiting for right fork");
forksArray[rightFork] = 0;
try{
Thread.sleep(5000);
}
catch(Exception e){
}
//Grab fork on the left
while(forksArray[leftFork]==0);
System.out.println("Thread "+id+" waiting for left fork");
forksArray[leftFork] = 0;
}
public void eat(){
System.out.println("Thread "+id+" eating.");
try{
Thread.sleep(2000);
}
catch(Exception e){
System.out.println(e);
}
}
public void putForks(){
System.out.println("Thread "+id+" putting forks down.");
forksArray[rightFork] = 1;
forksArray[leftFork] = 1;
}
}
}