The Dining Philosophers Problem — Using Java

Ashen Malaka
5 min readMay 3, 2019

--

One of the best classic examples which is used to describe synchronization issues in a multi-threaded background is the Dining Philosophers problem.

In this article we discuss what this problem is and what is the solution using following four segments.

01. Introduction

02. Solution

03. Implementation

04. Errors when implementing & How to overcome those errors

Now let’s see what are above mentioned segments with details.

01. Introduction

Dining Philosophers Diagram

Above diagram represents the problem. There are five philosophers(silent) who are marked as P1-P5 sitting around a circular table. They are spending their lives by eating and thinking. To eat there are five forks for them to share named 1–5. Also, to eat a philosopher needs to have forks in both of his hands. After eating the philosopher puts down the forks(both) and those forks can be picked by another philosopher who repeats the same thing. This is a cyclic procedure.

02. Solution

The goal is to come up with a procedure that the philosophers achieve their goal of eating and thinking without getting starved to death. Following pseudo code is the procedure to follow when solving this problem.

while(true){

think(); //Initially thinking about the whole universal things.

pick_up_left_fork(); //Readying to eat as philosopher gets hungry eventually.

pick_up_right_fork();

eat();

put_down_right_fork();

put_down_left_fork();

think(); //Back to start thinking as hungry is over.

}

According to above pseudo code each philosopher is initially thinking. After some time, the philosopher gets hungry and wishes to eat. To achieve this the philosopher reaches for the forks on his either side. When the philosopher is successful in getting both folks, he begins to eat. When he puts down both forks, those forks are available for his neighbor philosopher. This is how this works.

03. Implementation

Initially we take philosophers as classes that implement the Runnable interface so that we can turn them as separate threads. Each philosopher has access to two forks on his left and right sides.

Runnable interface in Philosopher class

Also, there is another method that instructs a philosopher to perform his preferred action: eat, think or getting two forks to eat.

doAction Method in Philosopher class

According to above code each action is simulated by suspending the invoking thread for a random amount of time. So, from that the execution order is not enforced by time alone.

To simulate acquiring a fork, we need to lock it so that no two philosopher threads acquire it at the same time. To achieve this, we use the synchronized keyword to acquire the internal monitor of the fork object and prevent other threads from doing the same. This is done in run() method in Philosopher class.

run() method in Philosopher class

This code segment describes: a philosopher thinks for a while and then decides to eat. Also, timestamps were added to each action, in order to understand the order in which events occur.

To start the whole process we create a class named DiningPhilosophers to create five philosophers as threads and to start all of them.

DiningPhilosophers class

We model each of the forks as generic Java objects and make as many of them as there are philosophers. We pass each Philosopher his left and right forks that he attempts to lock using the synchronized keyword.

Output is like following.

Output without Deadlock problem

04. Errors when implementing & How to overcome those errors

Above code is without the problem: Deadlock. If the DiningPhilosophers class is like following we have the problem.

DiningPhilosophers class with Deadlock

In this situation, each of the Philosophers has acquired his left fork, but can’t acquire right fork. Because his neighbor philosopher has already acquired it. This situation is commonly known as the circular wait and is one of the conditions that results in a deadlock and prevents the progress of the system.

Output of this code is as follows.

Output with Deadlock problem

Hence, to avoid a deadlock situation we need to make sure that the circular wait condition is broken. The simplest way to solve that is like follows:

All Philosophers reach for their left fork first, except one who first reaches for his right fork.

Following red colored section is the changed code segment to avoid deadlock situation. In this we introduced the condition that makes the last philosopher reach for his right fork first, instead of the left. This breaks the circular wait condition and we can avoid deadlock.

Code segment to avoid Deadlock problem

Now this code shows the output that indicates: all the philosophers get their chance to think and eat, without causing deadlock.

In this article we analyzed the famous Dining Philosophers problem using threads.

--

--

Ashen Malaka
Ashen Malaka

Written by Ashen Malaka

Associate Software Engineer @Davton Consulting | Final Year Undergraduate | University of Kelaniya | Traveller

Responses (1)