From 173458e5f215d8ffa023d0e7635bcb733fbf6822 Mon Sep 17 00:00:00 2001 From: 2210892 <2210892@stud.hs-mannheim.de> Date: Thu, 24 Oct 2024 21:49:25 +0200 Subject: [PATCH] Erweiterung PU1 und weiteres --- .classpath | 33 +++------------- eigenes/philosopher2/Philosopher.java | 55 ++++++++++++++++++++++++++ eigenes/philosopher3/Philosopher.java | 56 +++++++++++++++++++++++++++ eigenes/src/Arbitrator.java | 19 +++++++++ eigenes/src/Chopstick.java | 20 ++++++++++ eigenes/src/Philosopher.java | 43 ++++++++++++++++++++ 6 files changed, 198 insertions(+), 28 deletions(-) create mode 100644 eigenes/philosopher2/Philosopher.java create mode 100644 eigenes/philosopher3/Philosopher.java create mode 100644 eigenes/src/Arbitrator.java create mode 100644 eigenes/src/Chopstick.java create mode 100644 eigenes/src/Philosopher.java diff --git a/.classpath b/.classpath index f7e4a1d..41d3e7a 100644 --- a/.classpath +++ b/.classpath @@ -1,37 +1,14 @@ - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/eigenes/philosopher2/Philosopher.java b/eigenes/philosopher2/Philosopher.java new file mode 100644 index 0000000..99ae80a --- /dev/null +++ b/eigenes/philosopher2/Philosopher.java @@ -0,0 +1,55 @@ +package philosopher2; + +import src.Chopstick; + +public class Philosopher implements Runnable { + private final Chopstick leftChopstick; + private final Chopstick rightChopstick; + private final boolean isRightHanded; // Asymmetry flag + + public Philosopher(Chopstick leftChopstick, Chopstick rightChopstick, boolean isRightHanded) { + this.leftChopstick = leftChopstick; + this.rightChopstick = rightChopstick; + this.isRightHanded = isRightHanded; + } + + @Override + public void run() { + try { + while (true) { + think(); + if (isRightHanded) { + synchronized (rightChopstick) { + rightChopstick.pickUp(); + synchronized (leftChopstick) { + leftChopstick.pickUp(); + eat(); + leftChopstick.putDown(); + } + rightChopstick.putDown(); + } + } else { + synchronized (leftChopstick) { + leftChopstick.pickUp(); + synchronized (rightChopstick) { + rightChopstick.pickUp(); + eat(); + rightChopstick.putDown(); + } + leftChopstick.putDown(); + } + } + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void think() { + System.out.println(Thread.currentThread().getName() + " is thinking."); + } + + private void eat() { + System.out.println(Thread.currentThread().getName() + " is eating."); + } +} diff --git a/eigenes/philosopher3/Philosopher.java b/eigenes/philosopher3/Philosopher.java new file mode 100644 index 0000000..0093f37 --- /dev/null +++ b/eigenes/philosopher3/Philosopher.java @@ -0,0 +1,56 @@ +package philosopher3; + +import src.Chopstick; + +public class Philosopher implements Runnable { + private final Chopstick leftChopstick; + private final Chopstick rightChopstick; + + public Philosopher(Chopstick leftChopstick, Chopstick rightChopstick) { + this.leftChopstick = leftChopstick; + this.rightChopstick = rightChopstick; + } + + @Override + public void run() { + try { + while (true) { + think(); + if (tryToEat()) { + eat(); + } + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void think() { + System.out.println(Thread.currentThread().getName() + " is thinking."); + } + + private boolean tryToEat() throws InterruptedException { + synchronized (leftChopstick) { + leftChopstick.pickUp(); + if (!tryPickUpRightChopstick()) { + leftChopstick.putDown(); + return false; // Couldn't get both chopsticks, return to thinking + } + } + return true; + } + + private boolean tryPickUpRightChopstick() throws InterruptedException { + synchronized (rightChopstick) { + rightChopstick.pickUp(); + return true; + } + } + + private void eat() throws InterruptedException { + System.out.println(Thread.currentThread().getName() + " is eating."); + rightChopstick.putDown(); + leftChopstick.putDown(); + } +} + diff --git a/eigenes/src/Arbitrator.java b/eigenes/src/Arbitrator.java new file mode 100644 index 0000000..714d52e --- /dev/null +++ b/eigenes/src/Arbitrator.java @@ -0,0 +1,19 @@ +package src; + +import java.util.concurrent.Semaphore; + +public class Arbitrator { + private final Semaphore semaphore; + + public Arbitrator(int maxPhilosophers) { + this.semaphore = new Semaphore(maxPhilosophers - 1); // Allow up to N-1 philosophers to eat + } + + public void requestPermission(Philosopher philosopher) throws InterruptedException { + semaphore.acquire(); // Request permission to eat + } + + public void releasePermission(Philosopher philosopher) { + semaphore.release(); // Release permission after eating + } +} diff --git a/eigenes/src/Chopstick.java b/eigenes/src/Chopstick.java new file mode 100644 index 0000000..b86f381 --- /dev/null +++ b/eigenes/src/Chopstick.java @@ -0,0 +1,20 @@ +package src; + +public class Chopstick { + private boolean inUse = false; + + // Ein Philosophen-Thread nimmt das Stäbchen + public synchronized void pickUp() throws InterruptedException { + while (inUse) { + wait(); // Warten, bis das Stäbchen verfügbar ist + } + inUse = true; + } + + // Ein Philosophen-Thread legt das Stäbchen wieder zurück + public synchronized void putDown() { + inUse = false; + notifyAll(); // Andere wartende Philosophen benachrichtigen + } +} + diff --git a/eigenes/src/Philosopher.java b/eigenes/src/Philosopher.java new file mode 100644 index 0000000..4ee9760 --- /dev/null +++ b/eigenes/src/Philosopher.java @@ -0,0 +1,43 @@ +package src; +public class Philosopher implements Runnable { + private final Chopstick leftChopstick; + private final Chopstick rightChopstick; + private final Arbitrator arbitrator; + + public Philosopher(Chopstick leftChopstick, Chopstick rightChopstick, Arbitrator arbitrator) { + this.leftChopstick = leftChopstick; + this.rightChopstick = rightChopstick; + this.arbitrator = arbitrator; + } + + @Override + public void run() { + try { + while (true) { + think(); + arbitrator.requestPermission(this); // Request permission from the arbitrator + synchronized (leftChopstick) { + leftChopstick.pickUp(); + synchronized (rightChopstick) { + rightChopstick.pickUp(); + eat(); + rightChopstick.putDown(); + } + leftChopstick.putDown(); + } + arbitrator.releasePermission(this); // Release permission + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void think() { + System.out.println(Thread.currentThread().getName() + " is thinking."); + } + + private void eat() { + System.out.println(Thread.currentThread().getName() + " is eating."); + } +} +