From 0fc6dd421fa466f943f420a3f33855a2d764f88c Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Thu, 1 May 2025 14:10:09 +0200 Subject: [PATCH 1/8] test --- pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index 8139cfb..7005aaa 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -24,7 +24,7 @@ public class Philosopher extends Thread implements IPhilosopher { @Override public void setTable(Lock table) { - // TODO Auto-generated method stub + // TODO Auto-generated method stub// } -- 2.43.0 From 7723b7fb35df69f689bc2dd1bde292f9b1ff205e Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Thu, 1 May 2025 15:54:08 +0200 Subject: [PATCH 2/8] V1.0 --- .../src/main/java/pp/IPhilosopher.java | 5 + .../src/main/java/pp/Philosopher.java | 99 +++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java index edb96c8..d683c1f 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java @@ -18,6 +18,11 @@ public interface IPhilosopher { void stopPhilosopher(); + void signal(); + + boolean isEating(); + + default void log(int seat, String message) { synchronized (Philosopher.class) { for (var i = 1; i <= seat; i++) { diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index 7005aaa..8c400c7 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -1,20 +1,32 @@ package pp; import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.Condition; +import static pp.PhilosopherExperiment.*; + public class Philosopher extends Thread implements IPhilosopher { private int seat; + private IPhilosopher left; + private IPhilosopher right; + private Lock table; + private Condition canEat; + private boolean eating = false; + private boolean stopped = false; @Override public void setLeft(IPhilosopher left) { // TODO Auto-generated method stub // Cast auf Philosopher erforderlich + this.left = left; } @Override public void setRight(IPhilosopher right) { // TODO Auto-generated method stub // Cast auf Philosopher erforderlich + + this.right = right; } @Override @@ -26,11 +38,98 @@ public class Philosopher extends Thread implements IPhilosopher { public void setTable(Lock table) { // TODO Auto-generated method stub// + this.table = table; + this.canEat = table.newCondition(); } @Override public void stopPhilosopher() { // TODO Auto-generated method stub + this.stopped = true; + this.interrupt(); + } + + // Hauptlogik des Philosophen: Der Philosoph denkt, versucht zu essen, isst und beendet das Essen. + public void run() { + try { + while (!stopped) { + think(); // denkt eine Weile + beginEating(); // wartet, falls nötig, bis beide Nachbarn nicht essen + eat(); // isst eine zufällige Zeit + endEating(); // beendet das Essen und signalisiert Nachbarn + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + // Diese Methode wird aufgerufen, wenn der Philosoph mit dem Essen fertig ist. + // Sie setzt seinen Status zurück und signalisiert den Nachbarn, dass sie es nun versuchen können. + private void endEating() { + table.lock(); + try { + eating = false; + log(seat, "hat fertig gegessen"); + left.signal(); + right.signal(); + } finally { + table.unlock(); + } + } + + // Diese Methode simuliert das tatsächliche Essen mit einer zufälligen Dauer. + private void eat() throws InterruptedException { + Thread.sleep((long) (Math.random() * MAX_EATING_DURATION_MS)); + } + + // Diese Methode prüft, ob einer der Nachbarn gerade isst. + // Wenn ja, wartet dieser Philosoph auf seine Bedingung. + // Wenn beide frei sind, beginnt er zu essen. + private void beginEating() throws InterruptedException { + table.lock(); + try { + while (((Philosopher) left).eating || ((Philosopher) right).eating) { + log(seat, "wartet"); + canEat.await(); // wartet, bis signal() von einem anderen Philosophen aufgerufen wird + } + eating = true; + log(seat, "isst jetzt"); + } finally { + table.unlock(); + } + } + + + // Der Philosoph denkt für eine gewisse Zeit (zufällig), danach signalisiert er den Nachbarn, + // dass er nun fertig ist mit Denken, was eventuell anderen hilft zu essen. + private void think() throws InterruptedException { + log(seat, "denkt"); + Thread.sleep((long) (Math.random() * MAX_THINKING_DURATION_MS)); + table.lock(); + try { + left.signal(); + right.signal(); + } finally { + table.unlock(); + } + } + + // Diese Methode wird von anderen Philosophen aufgerufen, + // um diesen Philosophen zu wecken (z.B nach Ende einer Essensphase). + public void signal() { + table.lock(); + try { + canEat.signal(); + } finally { + table.unlock(); + } + } + + // Gibt zurück, ob dieser Philosoph aktuell isst – wichtig für die Nachbarn. + public boolean isEating() { + return eating; + } + } -- 2.43.0 From c53e2b09ee6d0e15890cb74adbcb5baf9b872fbd Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Thu, 1 May 2025 15:56:46 +0200 Subject: [PATCH 3/8] Update pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java --- pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index 8c400c7..56a4c3b 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -36,7 +36,7 @@ public class Philosopher extends Thread implements IPhilosopher { @Override public void setTable(Lock table) { - // TODO Auto-generated method stub// + // TODO Auto-generated method stub this.table = table; this.canEat = table.newCondition(); @@ -127,7 +127,7 @@ public class Philosopher extends Thread implements IPhilosopher { } } - // Gibt zurück, ob dieser Philosoph aktuell isst – wichtig für die Nachbarn. + // Gibt zurück, ob dieser Philosoph aktuell isst wichtig für die Nachbarn. public boolean isEating() { return eating; } -- 2.43.0 From 8291fbed75b921d5b7c2269bdc68b84265c66053 Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Sat, 3 May 2025 16:12:25 +0200 Subject: [PATCH 4/8] V1.1 (cast Philosopher) --- .../src/main/java/pp/IPhilosopher.java | 2 +- .../src/main/java/pp/Philosopher.java | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java index d683c1f..3b5e05d 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java @@ -20,7 +20,7 @@ public interface IPhilosopher { void signal(); - boolean isEating(); +// boolean isEating(); default void log(int seat, String message) { diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index 8c400c7..9e9663e 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -7,8 +7,8 @@ import static pp.PhilosopherExperiment.*; public class Philosopher extends Thread implements IPhilosopher { private int seat; - private IPhilosopher left; - private IPhilosopher right; + private Philosopher left; + private Philosopher right; private Lock table; private Condition canEat; private boolean eating = false; @@ -18,15 +18,14 @@ public class Philosopher extends Thread implements IPhilosopher { public void setLeft(IPhilosopher left) { // TODO Auto-generated method stub // Cast auf Philosopher erforderlich - this.left = left; + this.left = (Philosopher) left; } @Override public void setRight(IPhilosopher right) { // TODO Auto-generated method stub // Cast auf Philosopher erforderlich - - this.right = right; + this.right = (Philosopher) right; } @Override @@ -36,7 +35,7 @@ public class Philosopher extends Thread implements IPhilosopher { @Override public void setTable(Lock table) { - // TODO Auto-generated method stub// + // TODO Auto-generated method stub this.table = table; this.canEat = table.newCondition(); @@ -90,7 +89,7 @@ public class Philosopher extends Thread implements IPhilosopher { private void beginEating() throws InterruptedException { table.lock(); try { - while (((Philosopher) left).eating || ((Philosopher) right).eating) { + while (left.eating || right.eating) { log(seat, "wartet"); canEat.await(); // wartet, bis signal() von einem anderen Philosophen aufgerufen wird } @@ -128,8 +127,8 @@ public class Philosopher extends Thread implements IPhilosopher { } // Gibt zurück, ob dieser Philosoph aktuell isst – wichtig für die Nachbarn. - public boolean isEating() { - return eating; - } +// public boolean isEating() { +// return eating; +// } } -- 2.43.0 From 5761ad257ac33f1ead62ee177b95f87ec91daa47 Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Sat, 3 May 2025 16:16:55 +0200 Subject: [PATCH 5/8] Update pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java --- pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index 9e9663e..2df840d 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -126,7 +126,7 @@ public class Philosopher extends Thread implements IPhilosopher { } } - // Gibt zurück, ob dieser Philosoph aktuell isst – wichtig für die Nachbarn. + // Gibt zurück, ob dieser Philosoph aktuell isst wichtig für die Nachbarn. // public boolean isEating() { // return eating; // } -- 2.43.0 From 29c257adeadda2f036c696767da9e1cc0e953c86 Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Sat, 3 May 2025 20:31:10 +0200 Subject: [PATCH 6/8] final --- pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java | 3 +-- pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java | 8 +------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java index 3b5e05d..c6418d3 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/IPhilosopher.java @@ -18,9 +18,8 @@ public interface IPhilosopher { void stopPhilosopher(); - void signal(); -// boolean isEating(); + default void log(int seat, String message) { diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index 9e9663e..eb28836 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -91,7 +91,7 @@ public class Philosopher extends Thread implements IPhilosopher { try { while (left.eating || right.eating) { log(seat, "wartet"); - canEat.await(); // wartet, bis signal() von einem anderen Philosophen aufgerufen wird + canEat.await(); } eating = true; log(seat, "isst jetzt"); @@ -125,10 +125,4 @@ public class Philosopher extends Thread implements IPhilosopher { table.unlock(); } } - - // Gibt zurück, ob dieser Philosoph aktuell isst – wichtig für die Nachbarn. -// public boolean isEating() { -// return eating; -// } - } -- 2.43.0 From 82f41974d11f9305f6b1e28c4f848daf05d34921 Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Sat, 3 May 2025 20:56:09 +0200 Subject: [PATCH 7/8] dont need comment anymore adding volatile --- .../src/main/java/pp/Philosopher.java | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index eb28836..c1514c1 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -11,13 +11,14 @@ public class Philosopher extends Thread implements IPhilosopher { private Philosopher right; private Lock table; private Condition canEat; - private boolean eating = false; - private boolean stopped = false; + private volatile boolean eating = false; + private volatile boolean stopped = false; @Override public void setLeft(IPhilosopher left) { // TODO Auto-generated method stub // Cast auf Philosopher erforderlich + if (left == null) throw new IllegalArgumentException("Left philosopher must not be null."); this.left = (Philosopher) left; } @@ -25,6 +26,7 @@ public class Philosopher extends Thread implements IPhilosopher { public void setRight(IPhilosopher right) { // TODO Auto-generated method stub // Cast auf Philosopher erforderlich + if (right == null) throw new IllegalArgumentException("Right philosopher must not be null."); this.right = (Philosopher) right; } @@ -50,22 +52,20 @@ public class Philosopher extends Thread implements IPhilosopher { } - // Hauptlogik des Philosophen: Der Philosoph denkt, versucht zu essen, isst und beendet das Essen. public void run() { try { while (!stopped) { - think(); // denkt eine Weile - beginEating(); // wartet, falls nötig, bis beide Nachbarn nicht essen - eat(); // isst eine zufällige Zeit - endEating(); // beendet das Essen und signalisiert Nachbarn + think(); + beginEating(); + eat(); + endEating(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } - // Diese Methode wird aufgerufen, wenn der Philosoph mit dem Essen fertig ist. - // Sie setzt seinen Status zurück und signalisiert den Nachbarn, dass sie es nun versuchen können. + private void endEating() { table.lock(); try { @@ -78,14 +78,11 @@ public class Philosopher extends Thread implements IPhilosopher { } } - // Diese Methode simuliert das tatsächliche Essen mit einer zufälligen Dauer. private void eat() throws InterruptedException { Thread.sleep((long) (Math.random() * MAX_EATING_DURATION_MS)); } - // Diese Methode prüft, ob einer der Nachbarn gerade isst. - // Wenn ja, wartet dieser Philosoph auf seine Bedingung. - // Wenn beide frei sind, beginnt er zu essen. + private void beginEating() throws InterruptedException { table.lock(); try { @@ -101,8 +98,7 @@ public class Philosopher extends Thread implements IPhilosopher { } - // Der Philosoph denkt für eine gewisse Zeit (zufällig), danach signalisiert er den Nachbarn, - // dass er nun fertig ist mit Denken, was eventuell anderen hilft zu essen. + private void think() throws InterruptedException { log(seat, "denkt"); Thread.sleep((long) (Math.random() * MAX_THINKING_DURATION_MS)); @@ -115,8 +111,6 @@ public class Philosopher extends Thread implements IPhilosopher { } } - // Diese Methode wird von anderen Philosophen aufgerufen, - // um diesen Philosophen zu wecken (z.B nach Ende einer Essensphase). public void signal() { table.lock(); try { -- 2.43.0 From 28611e3e2f54ec438767cd0059ea219ba6b234aa Mon Sep 17 00:00:00 2001 From: Shahnam Javidnia <3015418@stud.hs-mannheim.de> Date: Sun, 4 May 2025 21:48:06 +0200 Subject: [PATCH 8/8] Random signal constructor --- .../src/main/java/pp/Philosopher.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java index c1514c1..636f3ad 100644 --- a/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java +++ b/pp.A1-CondPhilosophers/src/main/java/pp/Philosopher.java @@ -3,6 +3,7 @@ package pp; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Condition; import static pp.PhilosopherExperiment.*; +import java.util.Random; public class Philosopher extends Thread implements IPhilosopher { @@ -13,6 +14,13 @@ public class Philosopher extends Thread implements IPhilosopher { private Condition canEat; private volatile boolean eating = false; private volatile boolean stopped = false; + private final Random random; + + public Philosopher() { + this.random = new Random(); + this.seat = 0; + this.stopped = false; + } @Override public void setLeft(IPhilosopher left) { @@ -71,15 +79,15 @@ public class Philosopher extends Thread implements IPhilosopher { try { eating = false; log(seat, "hat fertig gegessen"); - left.signal(); - right.signal(); + left.canEat.signal(); + right.canEat.signal(); } finally { table.unlock(); } } private void eat() throws InterruptedException { - Thread.sleep((long) (Math.random() * MAX_EATING_DURATION_MS)); + Thread.sleep(random.nextInt(MAX_EATING_DURATION_MS)); } @@ -101,22 +109,14 @@ public class Philosopher extends Thread implements IPhilosopher { private void think() throws InterruptedException { log(seat, "denkt"); - Thread.sleep((long) (Math.random() * MAX_THINKING_DURATION_MS)); + Thread.sleep(random.nextInt(MAX_THINKING_DURATION_MS)); table.lock(); try { - left.signal(); - right.signal(); + left.canEat.signal(); + right.canEat.signal(); } finally { table.unlock(); } } - public void signal() { - table.lock(); - try { - canEat.signal(); - } finally { - table.unlock(); - } - } } -- 2.43.0