package diningphilosophers4;

/**
 * Ein Philosoph, der eine bestimmte Zeit denkt, danach essen moechte.
 * 
 * @author  Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet Osnabrueck
 * @date 14.05.2007
 */
public class Philosopher extends Thread {
	private ChopStick left;

	private ChopStick right;

	private int numberOfDiners;

	/**
	 * Konstruktor, der einen Philosophen erstellt und mit ChopSticks versieht.
	 * @param name Name des Philosophen
	 * @param l linkes Essstaebchen
	 * @param r rechtes Essstaebchen
	 */
	public Philosopher(int id, ChopStick l, ChopStick r) {
		setName("Philosopher" + id);
		left = l;
		right = r;
		numberOfDiners = 0;
	}

	/**
	 * Ausfuehrung des Threads
	 */
	public void run() {

		try {
			while (true) {
				// thinking
				System.out.printf("%s denkt nach.%n", getName());
				sleep((int) (Math.random() * 1000));
				// hungry
				System.out.printf("%s ist hungrig.%n", getName());

				right.get();
				// gotright chopstick
				System.out.printf("%s hat das rechte Staebchen.%n", getName());
				sleep(500);
				if (left.tryToGet()) {
					System.out
							.printf(
									"%s hat Prioritaet %d, besitzt das linke Staebchen und isst.%n",
									getName(), getPriority());
					// eating
					incrementDiner();
					sleep((int) (Math.random() * 1000));
					right.put();
					left.put();
					setPriority(Thread.NORM_PRIORITY);
				} else {
					int prioritaet = getPriority();
					setPriority(prioritaet < Thread.MAX_PRIORITY ? ++prioritaet
							: Thread.MAX_PRIORITY);
					right.put();
					
				}
			}
		} catch (java.lang.InterruptedException e) {
		}
	}

	public String toString() {
		return left + "<(" + getName() + ": " + numberOfDiners + " Diners)>"
				+ right;
	}

	public void incrementDiner() {
		numberOfDiners++;
	}
}
