Hello! I really need help with an exercise.
The exercise goes like this: Implement a version where a philosopher waits if a chopstick is already used by another philosopher. (You can use synchronized or Semaphores.) In this task
each philosopher should first pick up the left and then the right chopstick. Run the code a couple of times until you observe deadlock. (If it is hard to get a deadlock, modify the times in sleep.
--
After I've implemented my code (in Table Class):
public class Table { int nbrOfChopsticks; private boolean chopstick[]; //true if chopstick[i] is available public Table(int nbrOfSticks) { //nbrOfSticks == 5 nbrOfChopsticks = nbrOfSticks; chopstick = new boolean[nbrOfChopsticks]; for (int i = 0; i < nbrOfChopsticks; i++) { chopstick[i] = true; } } public synchronized void getLeft(int n) { //while the left chopstick is unavailable, wait in while loop for it to become available while (chopstick[n] == false) { try { //instruction pdf says modify time in wait if you have trouble getting deadlock (which I do) wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //philosopher n picks up its left chopstick //chopstick[n] is set to unavailable since it's picked up chopstick[n] = false; } public synchronized void getRight(int n) { //calculate the right chopstick position int pos = n + 1; if (pos == nbrOfChopsticks) { pos = 0; } /* while the right chopstick is not unavailable AND while the left chopstick is not picked up wait in the for loop */ while ((chopstick[pos] == false) && (chopstick[n] == true)) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //philosopher n picks up its right chopstick //made unavailable since it's picked up chopstick[pos] = false; } public synchronized void releaseLeft(int n) { //philosopher n puts down its left chopstick chopstick[n] = true; notifyAll(); } public synchronized void releaseRight(int n) { //philosopher n puts down its right chopstick int pos = n + 1; if (pos == nbrOfChopsticks) { pos = 0; } chopstick[pos] = true; notifyAll(); } }
Everything in the Table class was given by the teacher, I've only implemented code where the getLeft(int n) method waits while the left chopstick (chopstick[n]) is taken. Then I also made the getRight(int n) method wait while the right chopstick (chopstick[pos]) is taken AND while the left chopstick is not picked up. (Because it says that the philosopher should pick the left up first, then the right). Then I added notifyAll() on both the release methods.
It seems to say I'm supposed to get a deadlock and I don't get one. I have no idea what to do. Can I get help, please?
The philosopher class (we are not to make any changes here):
import java.util.logging.Level; import java.util.logging.Logger; public class Philosopher implements Runnable { private int id; private Table myTable; public Philosopher(int pid, Table tab) { id = pid; myTable = tab; } @Override public void run() { for (int i = 0; i < 100; i++) { try { //think System.out.println("Philosopher " + id + " thinks. Iteration " + i); Thread.sleep((int) (Math.random() * 100)); //pick up left chopstick myTable.getLeft(id); System.out.println("Philosopher " + id + " pick up left"); Thread.sleep((int) (Math.random() * 10)); //pick up right chopstick myTable.getRight(id); System.out.println("Philosopher " + id + " pick up right"); //eat System.out.println("Philosopher " + id + " eats. Iteration " + i); Thread.sleep((int) (Math.random() * 100)); //release left chopstick myTable.releaseLeft(id); System.out.println("Philosopher " + id + " drop left"); Thread.sleep((int) (Math.random() * 10)); //release right chopstick myTable.releaseRight(id); System.out.println("Philosopher " + id + " drop right"); Thread.sleep((int) (Math.random() * 10)); } catch (InterruptedException ex) { Logger.getLogger(Philosopher.class.getName()).log(Level.SEVERE, null, ex); } } } }
Main class (make no changes here):