// This is Java-like pseudocode, but NOT valid Java // because the signaling discipline and condition // variables are wrong. import Utilities.*; import Synchronization.*; class DiningServer extends MyObject { private boolean checkStarving = false; private int numPhils = 0; private int[] state = null; private ConditionVariable[] self = null; private static final int THINKING = 0, HUNGRY = 1, STARVING = 2, EATING = 3; public DiningServer(int numPhils, boolean checkStarving) { this.numPhils = numPhils; this.checkStarving = checkStarving; state = new int[numPhils]; for (int i = 0; i < numPhils; i++) state[i] = THINKING; self = new ConditionVariable[numPhils]; for (int i = 0; i < numPhils; i++) self[i] = new ConditionVariable(); } public void takeForks(int i) { hungryAndGetForks(i); } public void putForks(int i) { finishedEating(i); checkForkDown(left(i)); checkForkDown(right(i)); } private final int left(int i) { return (numPhils + i - 1) % numPhils; } private final int right(int i) { return (i + 1) % numPhils; } private void seeIfStarving(int k) { if (state[k] == HUNGRY && state[left(k)] != STARVING && state[right(k)] != STARVING) { state[k] = STARVING; } } private void test(int k, boolean checkStarving) { if (state[left(k)] != EATING && state[left(k)] != STARVING && (state[k] == HUNGRY || state[k] == STARVING) && state[right(k)] != STARVING && state[right(k)] != EATING) state[k] = EATING; else if (checkStarving) seeIfStarving(k); // simplistic naive check for starvation } private synchronized void hungryAndGetForks(int i) { state[i] = HUNGRY; test(i, false); if (state[i] != EATING) wait(self[i]); } private synchronized void finishedEating(int i) { state[i] = THINKING; } private synchronized void checkForkDown(int i) { test(i, checkStarving); if (state[i] == EATING) notify(self[i]); } }