Dining Philosophers problem in Java

The Problem of the Dining Philosophers illustrates a concurrency issue involving the distribution of scarce resources among conflicting processes.

Problem Statement

Imagine a dining table with a circle in the middle and five philosophers seated there. The illustration below shows that the dining table contains five chopsticks and a bowl of rice in the center.

A philosopher is either eating or thinking at any given time. A philosopher uses one chopstick from their left and one from their right when he wants to eat. A philosopher places both chopsticks back where they were when he wants to reflect. All philosophers start out by thinking. After a while, he becomes hungry and desires noodles. The philosopher scans both sides for the forks. The philosopher begins to eat after receiving both forks. He finishes his meal, sets the forks down, and resumes pondering. The forks that the philosopher sets down may be used by nearby philosophers.

The issue is utilized to create a scheduling method that ensures no philosopher will go hungry.

The following conditions must be followed:

• A philosopher will eat with both chopsticks (left and right).
• Any one of the nearby philosophers may choose the remaining branch, but not both.
• As long as both forks are accessible, a philosopher may eat noodles.
• A philosopher will set both forks down after eating and resume pondering.
• The other philosophers can choose those forks and proceed with the same method.
• Right and left philosophical neighbors are not permitted to eat together.

Approach

Dining Philosopher’s Problem in Practice

First, we have initialized the number of philosophers in the following application. The number of philosophers was the initial value for the two arrays, philosophers[] and chopsticks[].

We've constructed a class called Chopstick to implement the logic for chopsticks.

The acquire() method, which obtains a permit from this semaphore, is called the grab() method. It eliminates 1 permit from the system. If no permits are available, the active thread is disabled.

The release() function of the Semaphore class is called by the user-defined release() method. It issues the specified number of licences and advances each one by one.

Program

DiningPhilosophereProblem.java

``````// importing the required packages
import java.util.concurrent.Semaphore;
// Main class declaration
public class DiningPhilosophersProblem
{
static int philosopher = 5;
static Philosopher p[] = new Philosopher[philosopher];
static Chopstick c[] = new Chopstick[philosopher];
static class Chopstick
{
public Semaphore m = new Semaphore(1);
void grab()
{
// try block is used to prevent the stop of program execution due to errors
try
{
m.acquire();
}
catch (Exception ex)
{
ex.printStackTrace(System.out);
}
}
// release method
void release()
{
m.release();
}
// Boolean variable isFree() is used to check whether the chopstick is free or not
boolean isFree()
{
return m.availablePermits() > 0;
}
}
// extending to thread class
static class Philosopher extends Thread
{
public int n;
public Chopstick leftchopstick;
public Chopstick rightchopstick;
Philosopher(int num, Chopstick left, Chopstick right)
{
n = num;
leftchopstick = left;
rightchopstick = right;
}
// run method to run the thread
public void run()
{
while (true)
{
leftchopstick.grab();
System.out.println("Philosopher " + (n+1) + " holds left chopstick.");
rightchopstick.grab();
System.out.println("Philosopher " + (n+1) + " holds right chopstick.");

eat();

leftchopstick.release();
System.out.println("Philosopher " + (n+1) + " releases left chopstick.");
rightchopstick.release();
System.out.println("Philosopher " + (n+1) + " releases right chopstick.");
}
}
void eat()
{
try
{
int sleepTime = ThreadLocalRandom.current().nextInt(0, 1000);
System.out.println("Philosopher " + (n+1) + " eats for " + sleepTime +"ms");
}
catch (Exception ex)
{
ex.printStackTrace(System.out);
}
}
}
public static void main(String args[])
{
for (int i = 0; i < philosopher; i++)
{
c[i] = new Chopstick();
}
for (int i = 0; i < philosopher; i++)
{
p[i] = new Philosopher(i, c[i], c[(i + 1) % philosopher]);
p[i].start();
}
while (true)
{
try
{
boolean dl = true;
for (Chopstick ct : c)
{
if (ct.isFree())
{
dl = false;
break;
}
}
if(dl)
{
System.out.println("Everyone Eats");
break;
}
}
catch (Exception ex)
{
ex.printStackTrace(System.out);
}
}
System.out.println("Exit The Program!");
System.exit(0);
}
}
``````

Output

``````Philosopher 1 holds left chopstick.
Philosopher 3 holds left chopstick.
Philosopher 5 holds left chopstick.
Philosopher 4 holds left chopstick.
Philosopher 2 holds left chopstick.
Everyone Eats
Exit The Program!
``````