diff --git a/src/main/java/io/dama/ffi/parcoord/dining/cond/Philosopher.java b/src/main/java/io/dama/ffi/parcoord/dining/cond/Philosopher.java index 0c468c1..218312f 100644 --- a/src/main/java/io/dama/ffi/parcoord/dining/cond/Philosopher.java +++ b/src/main/java/io/dama/ffi/parcoord/dining/cond/Philosopher.java @@ -28,8 +28,8 @@ public class Philosopher extends Thread implements IPhilosopher { private Lock table; private Condition condition; - private boolean stop = false; - private boolean isEating = false; + private volatile boolean stop = false; + private volatile boolean isEating = false; private void log(String message) { synchronized (Philosopher.class) { @@ -40,6 +40,15 @@ public class Philosopher extends Thread implements IPhilosopher { } } + private void err(String message) { + synchronized (Philosopher.class) { + for (var i = 1; i <= this.seat; i++) { + System.err.print(" ".repeat(40)); + } + System.err.println(message); + } + } + @Override public void setLeft(IPhilosopher left) { this.left = (Philosopher) left; @@ -70,35 +79,39 @@ public class Philosopher extends Thread implements IPhilosopher { @Override public void run() { while (!this.stop) { + log("Philosopher " + seat + " is thinking"); this.sleepRandomDuration(PhilosopherExperiment.MAX_THINKING_DURATION_MS); + log("Philosopher " + seat + " is done thinking"); + this.table.lock(); try { - this.table.lock(); while (this.left.isEating || this.right.isEating) { - log("Philosopher " + seat + " is waiting for his neighbors to finish eating"); - this.left.condition.await(); - this.right.condition.await(); + log("Philosopher " + seat + " is waiting"); + this.condition.await(); + log("Philosopher " + seat + " is done waiting"); } - this.isEating = true; - log("Philosopher " + seat + " is taking chopsticks"); - this.sleepRandomDuration(PhilosopherExperiment.MAX_TAKING_TIME_MS); - log("Philosopher " + seat + " is eating"); - - this.sleepRandomDuration(PhilosopherExperiment.MAX_EATING_DURATION_MS); - log("Philosopher " + seat + " is done eating"); - - this.isEating = false; + log("Philosopher " + seat + " took chopsticks"); + this.isEating = true; } catch (InterruptedException e) { - log("Philosopher " + seat + " was interrupted"); - throw new RuntimeException(e); + this.err("Philosopher " + seat + " was interrupted while waiting for the table"); } finally { - this.condition.signalAll(); this.table.unlock(); } + + log("Philosopher " + seat + " is eating"); + this.sleepRandomDuration(PhilosopherExperiment.MAX_EATING_DURATION_MS); + log("Philosopher " + seat + " is done eating"); + + this.table.lock(); + this.isEating = false; + this.left.condition.signalAll(); + this.right.condition.signalAll(); + log("Philosopher " + seat + " is signaling"); + this.table.unlock(); } log("Philosopher " + seat + " has stopped"); diff --git a/src/main/java/io/dama/ffi/parcoord/dining/cond/PhilosopherExperiment.java b/src/main/java/io/dama/ffi/parcoord/dining/cond/PhilosopherExperiment.java index 6b4001f..1cf31e9 100644 --- a/src/main/java/io/dama/ffi/parcoord/dining/cond/PhilosopherExperiment.java +++ b/src/main/java/io/dama/ffi/parcoord/dining/cond/PhilosopherExperiment.java @@ -4,11 +4,11 @@ import java.util.concurrent.locks.ReentrantLock; public class PhilosopherExperiment { - static final int MAX_THINKING_DURATION_MS = 3000; // 3000 - static final int MAX_EATING_DURATION_MS = 3000; // 3000 - static final int MAX_TAKING_TIME_MS = 100; // 100 - static final int PHILOSOPHER_NUM = 5; - static final int EXP_DURATION_MS = 20000; + public static final int MAX_THINKING_DURATION_MS = 3000; // 3000 + public static final int MAX_EATING_DURATION_MS = 3000; // 3000 + public static final int MAX_TAKING_TIME_MS = 100; // 100 + public static final int PHILOSOPHER_NUM = 5; + public static final int EXP_DURATION_MS = 20000; static IPhilosopher[] philosophers = new Philosopher[PHILOSOPHER_NUM];