The Dining Philosophers problem was first presented by Dijkstra in 1965 on an exam.
Each philosopher alternates between thinking (analagous to CPU computation) and eating with shared chopsticks (analagous to accessing a shared IO device).
The implementation below uses synchronized to acquire the intrinsic lock to the chopstick to its left followed by acquiring the intrinsic lock to the chopstick to its right before eating.
The intristic locks are automatically released when the philosopher is done eating and continues to the thinking in the next iteration of the loop.
Chopstick[] chopsticks = { new Chopstick(0), new Chopstick(1),
new Chopstick(2), new Chopstick(3), new Chopstick(4) };
Philosopher[] philosophers = {
new Philosopher(chopsticks[0], chopsticks[1]),
new Philosopher(chopsticks[1], chopsticks[2]),
new Philosopher(chopsticks[2], chopsticks[3]),
new Philosopher(chopsticks[3], chopsticks[4]),
new Philosopher(chopsticks[4], chopsticks[0]),
};
join_void_fork_loop(philosophers, philosopher -> {
while(true) {
philosopher.think();
synchronized (philosopher.leftChopstick()) {
synchronized (philosopher.rightChopstick()) {
philosopher.eat();
}
}
}
});