Spring 99, CSE 428: Assignment 6


Distributed: March 5.
Due: March 25 in class.
Total maximum score: 100 points.

The purpose of this assignment is to provide experience with threads and programming in Java.

Note: Although the due time is March 25, I will be away during the week of March 22 (and without email access). Hence, you should start ahead thinking about this assignment, and discuss with me your questions, doubts, etc. before March 20. During my absence, the lectures will be given by Prof. Dale Miller, and he will collect the Hws on March 25.

- Catuscia Palamidessi

The problem of the dining philosophers

Imagine n philosophers sitting at a round table, with a chopstick in between every two philosophers, for a total of n chopsticks. In the middle of the table, there is a large bowl of rice.

The usual activity of a philosopher is thinking. However, from time to time, he gets hungry and tries to eat some rice. In order to eat, he needs to grab both the chopsticks at his left and at his right. He can grab only one chopstick at the time, and, of course, only if the neighbour is not already holding it. Once the philosopher succeeds to grab both chopsticks, he eats some rice, then releases the chopsticks, and goes back to thinking.

The typical problems which arise in this situation are

  1. the risk of deadlock, which occurs when each philosopher is holding one chopstick, and, egoistically, does not want to release it until he has eaten (so that nobody will ever be able to eat),
  2. the risk of global starvation, which occurs when each philopher takes a chopstick, finds out that the other one is already taken, hence generously releases it, and so on, so that also in this way nobody will ever eat.
There are also other risks, like the local starvation, which occurs when a philosopher is "too slow" and never succeeeds to eat because his neighbours always take the chopsticks before him. However, for our purposes here, we will not consider these other problems.

One way to solve the two problems mentioned above is by introducing the rule that each philosopher should, before attempting to grab the chopsticks, take a "ticket" from a common box. If the philosopher succeed to obtain a ticket, then he can try to take the chopsticks, and eat. Afterwards, he should put the tickets back in the box. In the box there are n-1 tickets, so that the situation described above (generating deadlock or global starvation) can never occur.

Implement the "Dining Philosophers" in Java, representing each philosopher as an active object (thread), and each chopstick as a passive object, following the idea of the "tickets box" described above to avoid deadlock/global starvation.

The classes of the philosophers, the chopsticks, and the tickets box should have the following interface:
interface Chopstick_interface {
  boolean is_free();
  void take();
  void release();
}

interface Tickets_box_interface {
  boolean tickets_available();
  void take_ticket(); 
  void release_ticket();
}

interface Philosopher_interface {
  void run();
}
Add the following main program:
public class Dining_philosophers {
  public static void main(String[] args) {
    int n = args.length;                       // n = number of philosophers
    Philosopher[] phils = new Philosopher[n];  // references to n philosophers
    Tickets_box b = new Tickets_box(n - 1);    // creates box with tickets
    Chopstick c_0 = new Chopstick(0);
    Chopstick left = c_0;
    for (int i = 0; i < n-1; i++) {
      Chopstick right = new Chopstick(i+1);  
      phils[i] = new Philosopher(args[i],left,right,b);  
      left = right;   
    }
    phils[n-1] = new Philosopher(args[n-1],left,c_0,b);
    for (int i = 0; i < n; i++) {
      phils[i].start();
    }
  }
}
Make sure that your objects signal the various activities going on, so that, when executed, you obtain an output like the following, in the case of 5 philosophers:
mix 31% java Dining_philosophers Plato Aristotle Zeno Eraclito Parmenide
Plato is thinking
Aristotle is thinking
Zeno is thinking
Eraclito is thinking
Parmenide is thinking
Plato is trying to eat ... Plato is eating ... Plato is thinking
Aristotle is trying to eat ... Aristotle is eating ... Aristotle is thinking
Zeno is trying to eat ... Eraclito is trying to eat ... Parmenide is trying to
eat ... Zeno is eating ... chopstick 3 already taken ... Parmenide is eating ... 
Eraclito is thinking
Parmenide is thinking
Zeno is thinking
Plato is trying to eat ... Plato is eating ... Plato is thinking
Aristotle is trying to eat ... Aristotle is eating ... Aristotle is thinking
Eraclito is trying to eat ... Eraclito is eating ... Eraclito is thinking
Parmenide is trying to eat ... Parmenide is eating ... Parmenide is thinking
Zeno is trying to eat ... Zeno is eating ... Zeno is thinking
Plato is trying to eat ... Plato is eating ... Plato is thinking
Aristotle is trying to eat ... Eraclito is trying to eat ... Parmenide is 
trying to eat ... Zeno is trying to eat ... Plato is trying to eat ... tickets
unavailable ... chopstick 1 already taken ... chopstick 2 already taken ... 
chopstick 3 already taken ... chopstick 4 already taken ... Plato is thinking
Aristotle is eating ... Aristotle is thinking
Eraclito is thinking
Parmenide is thinking
Zeno is thinking
Plato is trying to eat ... Plato is eating ... Plato is thinking
Aristotle is trying to eat ... Aristotle is eating ... Aristotle is thinking
Eraclito is trying to eat ... Eraclito is eating ... Eraclito is thinking
Parmenide is trying to eat ... Parmenide is eating ... Parmenide is thinking
Zeno is trying to eat ... Zeno is eating ... Zeno is thinking
^Z
Suspended
mix 32%
You don't need to obtain exactly this output; The above is just to give you an idea.

Format of the solution

Please give an hard copy of the source code to the substitute instructor (Prof. Dale Miller) by the due date. Furthermore, you should also email your source code to cg428@cse.psu.edu by the due date, so to allow us to check that your program runs correctly. Please send the code as an attachment (not by "cut-and-paste"), and use the 4 digits of your student id, followed by ".java", as the filename (example: if your id is 1001, then the file should have name 1001.java).

Please make sure that your program can be compiled and executed on Unix.

The format of the input should be as follows:

   % java Dining_philosophers n1 n2 n3 n4 ... nM
where n1 n2 n3 n4 ... nM is a sequence of names (the names of the philosophers).

Note: I know that there are lots of Java implementations of the Dining Philosophers available on the web, with fancy graphical features and diverse solutions to the deadlock problem. For the purpose of this assignment, however, you should stick to the interface described above and to the "tickets box" solution. Furthermore, you should not worry about graphical tools, a simple printed output like the above is more than sufficient.

If you want to see a typical demo of the problem, with 7 philosophers, go to http://www.personal.leeds.ac.uk/~ecldh/diners/RunDiners.html and wait a few minutes. Do not look at the code, because the solution is completely different and incompatible with the above interface.