[Problem Link]
- Solution here is to add some `ordering` on the resources (i.e. forks) requested by the processes (i.e. the philosophers).
- Identify the resource id’s (or fork id’s) that a philosopher is surround with
- We make sure the process requests the `lower` id fork before the `higher` id fork to avoid deadlocks
- Identify which fork (left or right) is the lower id fork and request in that order (i.e. first left then right first right then left)
- Make sure mutex’s are held until forks are released
class DiningPhilosophers {
private static ReentrantLock[] mutex = new ReentrantLock[] {
new ReentrantLock(),
new ReentrantLock(),
new ReentrantLock(),
new ReentrantLock(),
new ReentrantLock(),
};
public DiningPhilosophers() {
}
// call the run() method of any runnable to execute its code
public void wantsToEat(int philosopher,
Runnable pickLeftFork,
Runnable pickRightFork,
Runnable eat,
Runnable putLeftFork,
Runnable putRightFork) throws InterruptedException {
int left = philosopher;
int right = (philosopher-1) == -1 ? 4 : philosopher-1;
if (Math.min(left, right) == left) {
DiningPhilosophers.mutex[left].lock();
DiningPhilosophers.mutex[right].lock();
pickLeftFork.run();
pickRightFork.run();
} else {
DiningPhilosophers.mutex[right].lock();
DiningPhilosophers.mutex[left].lock();
pickRightFork.run();
pickLeftFork.run();
}
eat.run();
putLeftFork.run();
putRightFork.run();
DiningPhilosophers.mutex[left].unlock();
DiningPhilosophers.mutex[right].unlock();
}
} |
class DiningPhilosophers {
private static ReentrantLock[] mutex = new ReentrantLock[] {
new ReentrantLock(),
new ReentrantLock(),
new ReentrantLock(),
new ReentrantLock(),
new ReentrantLock(),
};
public DiningPhilosophers() {
}
// call the run() method of any runnable to execute its code
public void wantsToEat(int philosopher,
Runnable pickLeftFork,
Runnable pickRightFork,
Runnable eat,
Runnable putLeftFork,
Runnable putRightFork) throws InterruptedException {
int left = philosopher;
int right = (philosopher-1) == -1 ? 4 : philosopher-1;
if (Math.min(left, right) == left) {
DiningPhilosophers.mutex[left].lock();
DiningPhilosophers.mutex[right].lock();
pickLeftFork.run();
pickRightFork.run();
} else {
DiningPhilosophers.mutex[right].lock();
DiningPhilosophers.mutex[left].lock();
pickRightFork.run();
pickLeftFork.run();
}
eat.run();
putLeftFork.run();
putRightFork.run();
DiningPhilosophers.mutex[left].unlock();
DiningPhilosophers.mutex[right].unlock();
}
}