package pp; import java.util.concurrent.locks.Lock; import java.util.Random; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Philosopher extends Thread implements IPhilosopher { private Philosopher left; private Philosopher right; private int seat; private Lock table; private Condition tableIsFull; private final Random random = new Random(); private volatile boolean stopped; private volatile boolean eating; @Override public void setLeft(IPhilosopher left) { this.left = (Philosopher) left; } @Override public void setRight(IPhilosopher right) { this.right = (Philosopher) right; } @Override public void setSeat(int seat) { this.seat = seat; } @Override public void setTable(Lock table) { this.table = (ReentrantLock) table; tableIsFull = table.newCondition(); } @Override public void stopPhilosopher() { this.stopped = true; interrupt(); } private void eat() { table.lock(); try { while(this.left.eating || this.right.eating) { tableIsFull.await(); } this.eating = true; Thread.sleep(this.random.nextInt(PhilosopherExperiment.MAX_TAKING_TIME_MS)); table.unlock(); System.out.println("Philosoper at s: " + seat + " is eating"); Thread.sleep(this.random.nextInt(PhilosopherExperiment.MAX_EATING_DURATION_MS)); System.out.println("Philosopher at s: " + seat + " has finished eating."); this.eating = false; } catch (Exception e) { this.stopPhilosopher(); } finally { if(this.stopped) { table.unlock(); } } } private void think(){ table.lock(); try { right.tableIsFull.signal(); left.tableIsFull.signal(); table.unlock(); Thread.sleep(this.random.nextInt(PhilosopherExperiment.MAX_THINKING_DURATION_MS)); } catch (InterruptedException e) { this.stopPhilosopher(); } } @Override public void run() { try { while(!this.stopped) { think(); eat(); } } catch(Exception e) { Thread.currentThread().interrupt(); } } }