Resource Hierarchy Solution
The resource hierarchy solution to the Dining Philosophers problem works by assigning a unique id to the chopsticks (resources), numbered from 0 to (n−1). Philosophers always attempt to pick up the lower-numbered chopstick first before picking up the higher-numbered one. This forces all philosophers, except one, to act "left-handed" (they pick up the left chopstick first). One philosopher (the last one in the circle) will act as the "right-handed," picking up their right chopstick first. With this approach, we guarantee that at least one philosopher can proceed.
Philosopher class: To implement the Resource Hierarchy solution, only the run function in the philosopher class has to be modified: If the left chopstick id is lower, pick up left first, if the right chopstick id is lower, pick up the right first.
class HierarchyPhilosopher extends Philosopher {
HierarchyPhilosopher(int id, Chopstick leftChopstick, Chopstick rightChopstick) {
super(id, leftChopstick, rightChopstick);
}
@Override
run() {
while (!terminate()) {
think();
// pick up chopstick with lower id first
if(leftChopstick.getId() < rightChopstick.getId()){
pickUpLeftChopstick();
pickUpRightChopstick();
eat();
putDownLeftChopstick();
putDownRightChopstick();
} else {
pickUpRightChopstick();
pickUpLeftChopstick();
eat();
putDownRightChopstick();
putDownLeftChopstick();
}
}
}
}
Hierarchy Solution Evaluation
Now let us evaluate the Resource Hierarchy algorithm according to the key challenges and performance in simulations:
Aspect | Description |
---|---|
Deadlocks | The Resource Hierarchy Solution effectively prevents deadlocks via avoiding the circular-wait condition, as defined by Coffman. |
Starvation and Fairness | The Resource Hierarchy Solution, in itself, does not guarantee that a philosopher will get a chance to eat. We combine this approach with the FIFO (First in First Out) enhanced chopstick pickup, guaranteeing that philosophers will eventually get the chance to acquire their chopsticks. This transforms Resource Hierarchy to a starvation-free solution, with guaranteed acquiring of chopsticks. Unfortunately, in terms of eat-chance and eat-time fairness this is one of the worst performing solutions. |
Concurrency | Concurrency of the system is enhanced, compared to the naive approach. In practice, this approach should provide us with improved concurrency, since the longest path in the precedence graph is now shorter by one. The larger the number of philosophers, the less the benefit of only turning one philosopher "right-handed". |
Implementation | The changes required to implement are straightforward. |
Overhead and Scalability | Next to no overhead with the newly introduced logic. Highly scalable due to its decentralized nature, but the strict ordering of resources necessitates a highly static environment. |
Full knowledge about the system is necessary in advance to properly initialize the hierarchy. This is often hard to achieve in real-world systems. Dynamic changes are also hard to account for: What if a philosopher joins the table? We would essentially need to halt execution and re-initialize the whole table.
You can find the respective Simulation and Animation pages here:
Resource Hierarchy Simulation Resource Hierarchy AnimationAsymmetric Solution
The Asymmetric Solution takes a slightly different approach by assigning a specific order to the philosophers rather than to the chopsticks. Philosophers with an even number pick up the left chopstick first, while those with an odd number pick up the right chopstick first.
Philosopher class: To implement the Asymmetric solution, we again only have to modify the run function in the philosopher class. We assign philosophers with even id as left-handed, philosophers with odd id as right-handed.
class AsymmetricPhilosopher extends Philosopher {
AsymmetricPhilosopher(int id, Chopstick leftChopstick, Chopstick rightChopstick) {
super(id, leftChopstick, rightChopstick);
}
@Override
run() {
// philosophers with even id pick up left first, philosophers with odd id pick up right first
boolean even = id % 2 == 0;
while (!terminated()) {
think();
if(even){
pickUpLeftChopstick();
pickUpRightChopstick();
eat();
putDownLeftChopstick();
putDownRightChopstick();
} else {
pickUpRightChopstick();
pickUpLeftChopstick();
eat();
putDownRightChopstick();
putDownLeftChopstick();
}
}
}
}
Asymmetric Solution Evaluation
Let us again evaluate the given Algorithm according to the key challenges and performance in simulations:
Aspect | Description |
---|---|
Deadlocks | The Asymmetric Solution effectively prevents deadlocks by again avoiding the circular-wait condition. |
Starvation and Fairness | Again, the resource Asymmetric Solution does not guarantee that a philosopher will get a chance to eat by itself. We enhance this solution, using the FIFO-enabled pickup of chopsticks to transform it to a starvation-free solution, with a guarantee of eventual pickup. Similar to Resource Hierarchy, in terms of eat-chance and eat-time fairness this is one of the worst performing solutions. |
Concurrency | Concurrency of the system is improved further. We increase concurrency in our system due to the now minimal paths in the precedence graph. Compared to the naive and the Resource Hierarchy implementation, we achieve better concurrency. Note that this effect is often barely noticeable in simulation runs with five or four philosophers and low simulation times. |
Implementation | The changes required to implement this solution are quite minimal, again very straightforward and even a little more intuitive than Resource Hierarchy. |
Overhead and Scalability | Again, next to no overhead due to the introduced logic. Highly scalable to arbitrary numbers of philosophers. This approach is also more applicable to dynamic situations. |
You can find the respective Simulation and Animation pages here:
Asymmetric Simulation Asymmetric Animation