commit cc3050c940ea573474ee28b255b09048da8275d7 Author: 2wenty1ne Date: Tue Oct 22 16:41:53 2024 +0200 c diff --git a/src/src/Chopstick.java b/src/src/Chopstick.java new file mode 100644 index 0000000..ad36bae --- /dev/null +++ b/src/src/Chopstick.java @@ -0,0 +1,3 @@ +public class Chopstick { + +} \ No newline at end of file diff --git a/src/src/Philosopher.java b/src/src/Philosopher.java new file mode 100644 index 0000000..0407988 --- /dev/null +++ b/src/src/Philosopher.java @@ -0,0 +1,74 @@ +import java.util.Random; + +public class Philosopher extends Thread { + static final int MAX_THINKING_DURATION_MS = 1000; + static final int MAX_EATING_DURATION_MS = 3000; + static final int MAX_TAKING_TIME_MS = 1000; + + private final Chopstick left; + private final Chopstick right; + private final Random random; + private int eaten; + private final int seat; + + private volatile boolean stop; + + private void log(String message) { + synchronized (Philosopher.class) { + for (var i = 1; i <= this.seat; i++) { + System.out.print(" "); + } + System.out.println(threadId() + " " + message); + } + } + + public void stopPhilosopher() { + log("stopping"); + this.stop = true; + interrupt(); + } + + public Philosopher(int seat, Chopstick left, Chopstick right) { + this.stop = false; + this.seat = seat; + this.left = left; + this.right = right; + this.random = new Random(); + this.eaten = 0; + } + + @Override + public void run() { + log("starting"); + try { + while (!this.stop) { + think(); + eat(); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + log("stopped; eaten=" + this.eaten); + } + + private void think() throws InterruptedException { + Thread.sleep(this.random.nextInt(MAX_THINKING_DURATION_MS)); + } + + private void eat() throws InterruptedException { + log("try taking left"); + synchronized (this.left) { + log("left acquired"); + Thread.sleep(this.random.nextInt(MAX_TAKING_TIME_MS)); + log("try taking right"); + synchronized (this.right) { + log("right acquired"); + log("eating"); + this.eaten++; + Thread.sleep(this.random.nextInt(MAX_EATING_DURATION_MS)); + } + log("right released"); + } + log("left released"); + } +} \ No newline at end of file diff --git a/src/src/PhilosopherExperiment.java b/src/src/PhilosopherExperiment.java new file mode 100644 index 0000000..0b7cca1 --- /dev/null +++ b/src/src/PhilosopherExperiment.java @@ -0,0 +1,24 @@ +public class PhilosopherExperiment { + + static final int PHILOSOPHER_NUM = 3; + static final int EXP_DURATION_MS = 20000; + + public static void main(String... args) throws InterruptedException { + var chopsticks = new Chopstick[PHILOSOPHER_NUM]; + var philosophers = new Philosopher[PHILOSOPHER_NUM]; + for (var i = 0; i < PHILOSOPHER_NUM; i++) { + chopsticks[i] = new Chopstick(); + } + for (var i = 0; i < PHILOSOPHER_NUM; i++) { + philosophers[i] = new Philosopher(i, chopsticks[i], + chopsticks[(i + 1) % PHILOSOPHER_NUM]); + } + for (var i = 0; i < PHILOSOPHER_NUM; i++) { + philosophers[i].start(); + } + Thread.sleep(EXP_DURATION_MS); + for (var i = 0; i < PHILOSOPHER_NUM; i++) { + philosophers[i].stopPhilosopher(); + } + } +} \ No newline at end of file