import java.util.concurrent.Semaphore; /** * A class for a philosopher. Implements Runnable and therefore provides a run() method. A Philosopher always has a * fork to its left and to its right. These forks are modelled with semaphores. */ public class Philosopher implements Runnable { // some static variables for convenience // minimal and maximal times in ms protected static long minEatTime = 1; protected static long maxEatTime = 10; protected static long minThinkTime = 0; protected static long maxThinkTime = 10; // some variables for the simulation protected int ID; // used to identify the philosopher protected double waitingTime = 0; // sums total waiting times in microseconds protected int hasEaten = 0; // sums the number of meals protected volatile boolean stopSimulating = false; // flag to stop the simulation // variables for solving the problem protected Semaphore leftFork; // the left fork protected Semaphore rightFork; // the right fork /** * standard constructor for philosopher * @param leftFork a semaphore that represents the fork on the left hand side of the philosopher * @param rightFork a semaphore that represents the fork on the right hand side of the philosopher * @param ID an ID for the philosopher. This should be unique for every philosopher. */ public Philosopher(Semaphore leftFork, Semaphore rightFork, int ID) { this.leftFork = leftFork; this.rightFork = rightFork; this.ID = ID; } /** * get method for the amount of time waited * @return sum of waiting time */ public double getWaitingTime() { return waitingTime; } /** * get method for number of eaten meals * @return number of eaten meals */ public int getHasEaten() { return hasEaten; } /** * set method to set flag to stop simulation * @param stopSimulating new value of stopSimulating */ public void setStopSimulating(boolean stopSimulating) { this.stopSimulating = stopSimulating; } /** * method simulate thinking (runs for random amount of time) */ protected void think() { // time between lower and upper bound long thinkTime = (long) (Math.random() * (maxThinkTime - minThinkTime + 1) + minThinkTime); try { Thread.sleep(thinkTime); } catch (InterruptedException e) { throw new RuntimeException(e); } } /** * method to simulate eating (runs for random amount of time) */ protected void eat() { // time between lower and upper bound long eatTime = (long) (Math.random() * (maxEatTime - minEatTime + 1) + minEatTime); try { Thread.sleep(eatTime); hasEaten++; } catch (InterruptedException e) { throw new RuntimeException(e); } } /** * run method * stops when flag stopSimulating is true * is overridden in subclasses */ @Override public void run() { while (!stopSimulating) { // runs until it receives stop signal think(); // default philosopher just thinks } } }