On the next page is an outline of a solution to the dining-philosophers problem using monitors. This assignment requires implementing this solution using Javas condition variables.

Begin by creating five philosophers, each identified by a number 0...4. Each philosopher runs as a separate thread. Philosophers alternate between thinking and eating. When a philosopher wishes to eat, it invokes the method takeChopsticks(philNumber),where philNumber identifies the number of the philosopher wishing to eat. When a philosopher finishes eating, it invokes returnChopsticks(philNumber).

Your solution will implement the following interface:

public interface DiningServer
{
/* Called by a philosopher when it wishes to eat */
public void takeChopsticks(int philNumber);
/* Called by a philosopher when it is finished eating */
public void returnChopsticks(int philNumber);
}

The implementation of the interface follows the outline of the solution provided in Figure 1 on page 3. Use Javas condition variables to synchronize the activity of the philosophers and prevent deadlock.

Dining-Philosophers Solution Using Monitors

This is a deadlock-free solution to the dining-philosophers problem. This solution imposes the restriction that a philosopher may pick up her chopsticks only if both of them are available. To code this solution, we need to distinguish among three states in which we may find a philosopher. For this purpose, we introduce the following data structures:

enum State { THINKING, HUNGRY, EATING };
State states = new State[5];

Philosopher i can set the variable states[i] = State.EATING only if her two neighbors are not eating. That is, the conditions (states[(i + 4) % 5] != State.EATING) and (states[(i + 1) % 5] != State.EATING) hold.

We also need to declare:

Condition[] self = new Condition[5];

where philosopher i can delay herself when she is hungry but is unable to obtain the chopsticks she needs.

Now the description of the solution to the dining-philosophers problem. The distribution of the chopsticks is controlled by the monitor dp, which is an instance of the monitor type DiningPhilosophers. Figure 1 (on the next page) shows the definition of this monitor type using a Java-like pseudocode. Each philosopher, before starting to eat, must invoke the operation takeChopsticks(). This act may result in the suspension of the philosopher thread. After the successful completion of the operation, the philosopher may eat. After she eats, the philosopher invokes the returnChopsticks() operation and starts to think. Thus, philosopher i must invoke the operations takeChopsticks() and returnChopsticks() in the following sequence:

dp.takeChopsticks(i);
eat();
dp.returnChopsticks(i);

It is easy to show that this solution ensures that no two neighboring philosophers are eating simultaneously and that no deadlocks will occur. However, it is possible for a philosopher to starve to death. This assignment does NOT require a solution to that problem.

monitor DiningPhilosophers
{
enum State { THINKING, HUNGRY, EATING };
State[] states = new State[5];
Condition[] self = new Condition[5];
public DiningPhilosophers
{
for (int i = 0; i < 5; i++) states[i] = State.THINKING;
}
public void takeChopsticks(int i)
{
states[i] = State.HUNGRY;
test(i);
if (states[i] != State.EATING) self[i].wait;
}
public void returnChopsticks(int i)
{
states[i] = State.THINKING;
// test left and right neighbors
test((i + 4) % 5);
test((i + 1) % 5);
}
private void test(int i)
{
if ((states[(i + 4) % 5] != State.EATING) &&
(states[i] == State.HUNGRY) &&
(states[(i + 1) % 5] != State.EATING))
{
states[i] = State.EATING;
self[i].signal;
}
}
}

Figure 1

Additional Design Requirements

1. The driver class is the class Assignment2 and it should only contain only one method, main. The main method creates the dining philosopher object and an instance of each philosopher followed by starting the execution of each philosopher.

2. When a philosopher is thinking have the philosopher print: Philosopher i is thinking." with i being the number of the philosopher who is thinking. After the philosopher prints that it is thinking have the philosopher sleep for a random amount of time. The SleepUtilities class from the Factory.java program provides the ability for a thread to sleep.

3. When a philosopher is eating have the philosopher print: Philosopher i is eating." with i being the number of the philosopher who is eating. After the philosopher prints that it is eating have the philosopher sleep for a random amount of time. The SleepUtilities class from the Factory.java program provides the ability for a thread to sleep.

4. When a philosopher acquires both of its chopsticks have the DiningPhilosopher object print: Philosopher i acquired its left and right chopsticks." with i being the number of the philosopher who acquired its chopsticks. When a philosopher releases both of its chopsticks have the DiningPhilosopher object print: Philosopher i released its left and right chopsticks." with i being the number of the philosopher who released its chopsticks.

5. Tip: You must make your program as modular as possible, not placing all your code in one .java file. You must create multiple classes as you need. Methods should be reasonably small following the guidance that "A function should do one thing, and do it well." You will lose a lot of points for code readability if you dont make your program as modular as possible. But, do not go overboard on creating classes and methods. Your common sense should guide your creation of classes and methods.

6. Do NOT use your own packages in your program. If you see the keyword package on the top line of any of your .java files then you created a package. Create every .java file in the src folder of your Eclipse project

7. Do NOT use any graphical user interface code in your program!

8. Do NOT write any comments for your code. If you make your code as modular as possible then anyone reading your code will easily be able to determine the codes task.

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.