Friday, 18 September 2015

Dining philosopher's synchronization problem implemented using Java........

here is the code .....


       

public class DiningPhilosopherProblem {
 // Makes the code more readable.
 public static class ChopStick {
  // Make sure only one philosopher can have me at any time.
  Lock up = new ReentrantLock();
  // Who I am.
  private final int id;

  public ChopStick(int id) {
   this.id = id;
  }

  public boolean pickUp(Philosopher who, String where) throws InterruptedException {
   if (up.tryLock(10, TimeUnit.MILLISECONDS)) {
    System.out.println(who + " picked up " + where + " " + this);
    return true;
   }
   return false;
  }

  public void putDown(Philosopher who, String name) {
   up.unlock();
   System.out.println(who + " put down " + name + " " + this);
  }

  @Override
  public String toString() {
   return "Chopstick-" + id;
  }
 }

 // One philosoper.
 public static class Philosopher implements Runnable {
  // Which one I am.
  private final int id;
  // The chopsticks on either side of me.
  private final ChopStick leftChopStick;
  private final ChopStick rightChopStick;
  // Am I full?
  volatile boolean isTummyFull = false;
  // To randomize eat/Think time
  private Random randomGenerator = new Random();
  // Number of times I was able to eat.
  private int noOfTurnsToEat = 0;

  /**
   * **
   *
   * @param id Philosopher number
   *
   * @param leftChopStick
   * @param rightChopStick
   */
  public Philosopher(int id, ChopStick leftChopStick, ChopStick rightChopStick) {
   this.id = id;
   this.leftChopStick = leftChopStick;
   this.rightChopStick = rightChopStick;
  }

  @Override
  public void run() {

   try {
    while (!isTummyFull) {
     // Think for a bit.
     think();
     // Make the mechanism obvious.
     if (leftChopStick.pickUp(this, "left")) {
      if (rightChopStick.pickUp(this, "right")) {
       // Eat some.
       eat();
       // Finished.
       rightChopStick.putDown(this, "right");
      }
      // Finished.
      leftChopStick.putDown(this, "left");
     }
    }
   } catch (Exception e) {
    // Catch the exception outside the loop.
    e.printStackTrace();
   }
  }

  private void think() throws InterruptedException {
   System.out.println(this + " is thinking");
   Thread.sleep(randomGenerator.nextInt(1000));
  }

  private void eat() throws InterruptedException {
   System.out.println(this + " is eating");
   noOfTurnsToEat++;
   Thread.sleep(randomGenerator.nextInt(1000));
  }

  // Accessors at the end.
  public int getNoOfTurnsToEat() {
   return noOfTurnsToEat;
  }

  @Override
  public String toString() {
   return "Philosopher-" + id;
  }
 }
 // How many to test with.
 private static final int NO_OF_PHILOSOPHER = 50;
 //private static final int SIMULATION_MILLIS = 1000 * 60 * 8;
 private static final int SIMULATION_MILLIS = 1000 * 10;

 public static void main(String args[]) throws InterruptedException {
  ExecutorService executorService = null;

  Philosopher[] philosophers = null;
  try {

   philosophers = new Philosopher[NO_OF_PHILOSOPHER];

   //As many forks as Philosophers
   ChopStick[] chopSticks = new ChopStick[NO_OF_PHILOSOPHER];
   // Cannot do this as it will fill the whole array with the SAME chopstick.
   //Arrays.fill(chopSticks, new ReentrantLock());
   for (int i = 0; i < NO_OF_PHILOSOPHER; i++) {
    chopSticks[i] = new ChopStick(i);
   }

   executorService = Executors.newFixedThreadPool(NO_OF_PHILOSOPHER);

   for (int i = 0; i < NO_OF_PHILOSOPHER; i++) {
    philosophers[i] = new Philosopher(i, chopSticks[i], chopSticks[(i + 1) % NO_OF_PHILOSOPHER]);
    executorService.execute(philosophers[i]);
   }
   // Main thread sleeps till time of simulation
   Thread.sleep(SIMULATION_MILLIS);
   // Stop all philosophers.
   for (Philosopher philosopher: philosophers) {
    philosopher.isTummyFull = true;
   }

  } finally {
   // Close everything down.
   executorService.shutdown();

   // Wait for all thread to finish
   while (!executorService.isTerminated()) {
    Thread.sleep(1000);
   }

   // Time for check
   for (Philosopher philosopher: philosophers) {
    System.out.println(philosopher + " => No of Turns to Eat =" + philosopher.getNoOfTurnsToEat());
   }
  }
 }
}
       
 

No comments:

Post a Comment