import java.util.*;

class Chopstick {
  private boolean locked=false;
  
  public boolean islocked()
  {
  	return locked;
  }
  
  public void lock()
  {
  	locked=true;
  }
  
  public void unlock()
  {
  	locked=false;
  }
}

class Philosopher extends Thread {
  private static Random rand = new Random();
  private static int counter = 0;
  private int number = counter++;
  private Chopstick leftChopstick;
  private Chopstick rightChopstick;
  private int noOfEating;
  
  public Philosopher(Chopstick left, Chopstick right, int eatingCount) {
    leftChopstick = left;
    rightChopstick = right;
    this.noOfEating=eatingCount;
    start();
  }
  
  public void think() {
    System.out.println(this + " is thinking.");
    try {
        sleep(rand.nextInt(1000));
      } catch(InterruptedException e) {
        throw new RuntimeException(e);
      }
  }
  
  public void eat() {
  	synchronized(leftChopstick) {
  		while(leftChopstick.islocked())
  		{
  			try
  			{
  				leftChopstick.wait();
  			}
  			catch(InterruptedException e)
  			{
  				throw new RuntimeException(e);
  			}
  		}
  		leftChopstick.lock();
  		
  		synchronized(rightChopstick) {
      	while(rightChopstick.islocked())
  		{
  			try
  			{
  				rightChopstick.wait();
  			}
  			catch(InterruptedException e)
  			{
  				throw new RuntimeException(e);
  			}
  		}
  		rightChopstick.lock();
  		System.out.println(this + " is eating.");
        try{
        	sleep(rand.nextInt(1000));
        } catch(InterruptedException e) {
        	throw new RuntimeException(e);
        }
        
        rightChopstick.unlock();
        rightChopstick.notify();
      }
      
      leftChopstick.unlock();
      leftChopstick.notify();      
    }
  }
  
  public String toString() {
    return "Philosopher-" + number;
  }
  
  public void run() {
    for(int i=0;i<this.noOfEating;i++)
    {
      think();
      eat();
    }
  }
}

public class DiningPhilosophers {
  public static void main(String[] args) {
    if(args.length !=2) {
      System.err.println("usage:\n" +
        "java DiningPhilosophers numberOfPhilosophers numberOfEatingsAllowed."); 
      System.exit(1);
    }
    
    Philosopher[] philosopher =
      new Philosopher[Integer.parseInt(args[0])];
    Chopstick
      left = new Chopstick(),
      right = new Chopstick(),
      first = left;
    int i = 0;
    while(i < philosopher.length - 1) {
      philosopher[i++] =
        new Philosopher(left, right, Integer.parseInt(args[1]));
      left = right;
      right = new Chopstick();
    }
    
    if(philosopher.length == 1)
    first=right;
    
    philosopher[i] = new Philosopher(first, left, Integer.parseInt(args[1]));
  }
} 