Dining Philosophers with No Hold and Wait

Here's a monitor-based solution to the Dining Philosopher's problem that avoids deadlock by using block allocation. First, the program:
cobegin
Philosophers P;
while (1) {    // Philosopher 0
    Think;
    StartEating(0);
    Eat;
    StopEating(0);
    }
||
while (1)  {    // Philosopher 1
    Think;
    StartEating(1);
    Eat;
    StopEating(1);
    }
||
...
||
while (1)  {    // Philosopher 4
    Think;
    StartEating(4);
    Eat;
    StopEating(4);
    }
coend;
A Hoare-style monitor for Philosophers:
monitor Philosophers {
private:
    int free[5] = {1, 1, 1, 1, 1};
    // invariant: for all i, free[i] is 0 or 1
    condition canEat[5]; // canEat[i] = free[i] && free[(i + 1) % 5]
public:
    void entry StartEating (int p) {
        if (!(free[p] && free[(p + 1) % 5])) canEat[p].wait;
        free[p] = 0;
        free[(p + 1) % 5] = 0;
    }

    void entry StopEating (int p) {
        free[p] = 1;
        free[(p + 1) % 5] = 1;
        if (free[(p - 1) % 5]) canEat[(p - 1) % 5].signal;
        if (free[(p + 1) % 5] && free[(p + 2) % 5]) canEat[(p + 1) % 5].signal;
        }
};

A Java-style monitor for Philosophers:
class Philosophers {
    int free[5] = {1, 1, 1, 1, 1};

    public synchronized void StartEating (int p) {
        while (!(free[p] && free[(p + 1) % 5])) wait();
        free[p] = 0;
        free[(p + 1) % 5] = 0;
    }

    public synchronized void StopEating (int p) {
        free[p] = 1;
        free[(p + 1) % 5] = 1;
        notifyAll();
        }
}