From fbb4d157a557055e267db5e13b458414285d35a1 Mon Sep 17 00:00:00 2001 From: Sandro Leuchter Date: Fri, 8 Nov 2024 07:24:41 +0100 Subject: [PATCH] initial --- src/pp.06.01.SynchInterrupt/README.md | 7 ++ src/pp.06.01.SynchInterrupt/justfile | 14 ++++ src/pp.06.01.SynchInterrupt/pom.xml | 60 ++++++++++++++++ .../src/main/java/pp/Task.java | 46 +++++++++++++ .../README.md | 7 ++ src/pp.06.01.SynchInterrupt_solution/justfile | 13 ++++ src/pp.06.01.SynchInterrupt_solution/pom.xml | 60 ++++++++++++++++ .../src/main/java/pp/Task.java | 46 +++++++++++++ .../src/main/java/pp/TaskInterruptably.java | 55 +++++++++++++++ .../src/main/java/pp/TaskRegular.java | 58 ++++++++++++++++ src/pp.06.02-LockTiming/README.md | 7 ++ src/pp.06.02-LockTiming/justfile | 13 ++++ src/pp.06.02-LockTiming/pom.xml | 68 +++++++++++++++++++ .../src/main/java/pp/ExpUnsynchronized.java | 18 +++++ .../src/main/java/pp/Experiment.java | 40 +++++++++++ src/pp.06.02-LockTiming_solution/README.md | 7 ++ src/pp.06.02-LockTiming_solution/justfile | 16 +++++ src/pp.06.02-LockTiming_solution/pom.xml | 68 +++++++++++++++++++ .../src/main/java/pp/ExpReadWriteLock.java | 43 ++++++++++++ .../main/java/pp/ExpReadWriteLockLombok.java | 22 ++++++ .../src/main/java/pp/ExpReentrantLock.java | 36 ++++++++++ .../main/java/pp/ExpReentrantLockLombok.java | 23 +++++++ .../src/main/java/pp/ExpStampedLock.java | 42 ++++++++++++ .../src/main/java/pp/ExpSynchronized.java | 18 +++++ .../main/java/pp/ExpSynchronizedLombok.java | 22 ++++++ .../src/main/java/pp/ExpUnsynchronized.java | 18 +++++ .../src/main/java/pp/Experiment.java | 40 +++++++++++ .../src/main/java/pp/Main.java | 34 ++++++++++ 28 files changed, 901 insertions(+) create mode 100644 src/pp.06.01.SynchInterrupt/README.md create mode 100644 src/pp.06.01.SynchInterrupt/justfile create mode 100644 src/pp.06.01.SynchInterrupt/pom.xml create mode 100644 src/pp.06.01.SynchInterrupt/src/main/java/pp/Task.java create mode 100644 src/pp.06.01.SynchInterrupt_solution/README.md create mode 100644 src/pp.06.01.SynchInterrupt_solution/justfile create mode 100644 src/pp.06.01.SynchInterrupt_solution/pom.xml create mode 100644 src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/Task.java create mode 100644 src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskInterruptably.java create mode 100644 src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskRegular.java create mode 100644 src/pp.06.02-LockTiming/README.md create mode 100644 src/pp.06.02-LockTiming/justfile create mode 100644 src/pp.06.02-LockTiming/pom.xml create mode 100644 src/pp.06.02-LockTiming/src/main/java/pp/ExpUnsynchronized.java create mode 100644 src/pp.06.02-LockTiming/src/main/java/pp/Experiment.java create mode 100644 src/pp.06.02-LockTiming_solution/README.md create mode 100644 src/pp.06.02-LockTiming_solution/justfile create mode 100644 src/pp.06.02-LockTiming_solution/pom.xml create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLock.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLockLombok.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLock.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLockLombok.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpStampedLock.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronized.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronizedLombok.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpUnsynchronized.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/Experiment.java create mode 100644 src/pp.06.02-LockTiming_solution/src/main/java/pp/Main.java diff --git a/src/pp.06.01.SynchInterrupt/README.md b/src/pp.06.01.SynchInterrupt/README.md new file mode 100644 index 0000000..fbcf8fa --- /dev/null +++ b/src/pp.06.01.SynchInterrupt/README.md @@ -0,0 +1,7 @@ +# Laboraufgabe "Unterbrechbarkeit von Threads, die blockiert sind" +- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-01-SynchInterrupt.html) +- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-unterbrechbarkeit-von-threads-die-blockiert-sind") + +# Materialien +- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html) +- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html) diff --git a/src/pp.06.01.SynchInterrupt/justfile b/src/pp.06.01.SynchInterrupt/justfile new file mode 100644 index 0000000..66a8c95 --- /dev/null +++ b/src/pp.06.01.SynchInterrupt/justfile @@ -0,0 +1,14 @@ + +default: + just exec pp.Task "" + +exec class args: compile + mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}} +clean: + mvn clean +compile: + mvn compile +test: compile + mvn test +javadoc: + mvn javadoc:javadoc diff --git a/src/pp.06.01.SynchInterrupt/pom.xml b/src/pp.06.01.SynchInterrupt/pom.xml new file mode 100644 index 0000000..268d911 --- /dev/null +++ b/src/pp.06.01.SynchInterrupt/pom.xml @@ -0,0 +1,60 @@ + + 4.0.0 + pp + pp.06.01.SynchInterrupt + 1.0-SNAPSHOT + jar + + + 10 + UTF-8 + + + + org.junit.jupiter + junit-jupiter + 5.10.0 + test + + + org.projectlombok + lombok + 1.18.30 + provided + + + net.jcip + jcip-annotations + 1.0 + provided + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.9.0 + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + private + en_US + + + + + diff --git a/src/pp.06.01.SynchInterrupt/src/main/java/pp/Task.java b/src/pp.06.01.SynchInterrupt/src/main/java/pp/Task.java new file mode 100644 index 0000000..5b87201 --- /dev/null +++ b/src/pp.06.01.SynchInterrupt/src/main/java/pp/Task.java @@ -0,0 +1,46 @@ +package pp; + +public class Task extends Thread { + private volatile boolean stop = false; + + public Task(String name) { + setName(name); + } + + public void kill() { + System.out.printf("%s: killing...\n", getName()); + this.stop = true; + interrupt(); + } + + @Override + public void run() { + System.out.printf("%s: startup\n", getName()); + while (!this.stop) { + try { + synchronized (Task.class) { + System.out.printf("%s: working\n", getName()); + Thread.sleep(8000); + } + } catch (InterruptedException e) { + System.out.printf("%s: interrupted\n", getName()); + } + } + System.out.printf("%s: finished\n", getName()); + } + + public static void main(String... args) throws InterruptedException { + var t1 = new Task("T1"); + var t2 = new Task("T2"); + var t3 = new Task("T3"); + t1.start(); + Thread.sleep(1000); + t2.start(); + t3.start(); + t2.kill(); + t3.kill(); + t1.kill(); + t1.join(); + t2.join(); + } +} diff --git a/src/pp.06.01.SynchInterrupt_solution/README.md b/src/pp.06.01.SynchInterrupt_solution/README.md new file mode 100644 index 0000000..fbcf8fa --- /dev/null +++ b/src/pp.06.01.SynchInterrupt_solution/README.md @@ -0,0 +1,7 @@ +# Laboraufgabe "Unterbrechbarkeit von Threads, die blockiert sind" +- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-01-SynchInterrupt.html) +- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-unterbrechbarkeit-von-threads-die-blockiert-sind") + +# Materialien +- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html) +- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html) diff --git a/src/pp.06.01.SynchInterrupt_solution/justfile b/src/pp.06.01.SynchInterrupt_solution/justfile new file mode 100644 index 0000000..decb6c6 --- /dev/null +++ b/src/pp.06.01.SynchInterrupt_solution/justfile @@ -0,0 +1,13 @@ +default: + just exec pp.Task "" + +exec class args: compile + mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}} +clean: + mvn clean +compile: + mvn compile +test: compile + mvn test +javadoc: + mvn javadoc:javadoc diff --git a/src/pp.06.01.SynchInterrupt_solution/pom.xml b/src/pp.06.01.SynchInterrupt_solution/pom.xml new file mode 100644 index 0000000..50c3565 --- /dev/null +++ b/src/pp.06.01.SynchInterrupt_solution/pom.xml @@ -0,0 +1,60 @@ + + 4.0.0 + pp + pp.06.01.SynchInterrupt_solution + 1.0-SNAPSHOT + jar + + + 10 + UTF-8 + + + + org.junit.jupiter + junit-jupiter + 5.10.0 + test + + + org.projectlombok + lombok + 1.18.30 + provided + + + net.jcip + jcip-annotations + 1.0 + provided + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.9.0 + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + private + en_US + + + + + diff --git a/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/Task.java b/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/Task.java new file mode 100644 index 0000000..5b87201 --- /dev/null +++ b/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/Task.java @@ -0,0 +1,46 @@ +package pp; + +public class Task extends Thread { + private volatile boolean stop = false; + + public Task(String name) { + setName(name); + } + + public void kill() { + System.out.printf("%s: killing...\n", getName()); + this.stop = true; + interrupt(); + } + + @Override + public void run() { + System.out.printf("%s: startup\n", getName()); + while (!this.stop) { + try { + synchronized (Task.class) { + System.out.printf("%s: working\n", getName()); + Thread.sleep(8000); + } + } catch (InterruptedException e) { + System.out.printf("%s: interrupted\n", getName()); + } + } + System.out.printf("%s: finished\n", getName()); + } + + public static void main(String... args) throws InterruptedException { + var t1 = new Task("T1"); + var t2 = new Task("T2"); + var t3 = new Task("T3"); + t1.start(); + Thread.sleep(1000); + t2.start(); + t3.start(); + t2.kill(); + t3.kill(); + t1.kill(); + t1.join(); + t2.join(); + } +} diff --git a/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskInterruptably.java b/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskInterruptably.java new file mode 100644 index 0000000..dee626c --- /dev/null +++ b/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskInterruptably.java @@ -0,0 +1,55 @@ +package pp; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class TaskInterruptably extends Thread { + private volatile boolean stop = false; + private static Lock lock = new ReentrantLock(); + + public TaskInterruptably(String name) { + setName(name); + } + + public void kill() { + System.out.printf("%s: killing...\n", getName()); + this.stop = true; + interrupt(); + } + + @Override + public void run() { + System.out.printf("%s: startup\n", getName()); + while (!this.stop) { + try { + lock.lockInterruptibly(); + try { + System.out.printf("%s: working\n", getName()); + Thread.sleep(8000); + } catch (InterruptedException e) { + System.out.printf("%s: interrupted (inner)\n", getName()); + } finally { + lock.unlock(); + } + } catch (InterruptedException e) { + System.out.printf("%s: interrupted (outer)\n", getName()); + } + } + System.out.printf("%s: finished\n", getName()); + } + + public static void main(String... args) throws InterruptedException { + var t1 = new TaskInterruptably("T1"); + var t2 = new TaskInterruptably("T2"); + var t3 = new TaskInterruptably("T3"); + t1.start(); + Thread.sleep(1000); + t2.start(); + t3.start(); + t2.kill(); + t3.kill(); + t1.kill(); + t1.join(); + t2.join(); + } +} diff --git a/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskRegular.java b/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskRegular.java new file mode 100644 index 0000000..78204c6 --- /dev/null +++ b/src/pp.06.01.SynchInterrupt_solution/src/main/java/pp/TaskRegular.java @@ -0,0 +1,58 @@ +package pp; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class TaskRegular extends Thread { + private volatile boolean stop = false; + private static Lock lock = new ReentrantLock(); + + public TaskRegular(String name) { + setName(name); + } + + public void kill() { + System.out.printf("%s: killing...\n", getName()); + this.stop = true; + interrupt(); + } + + @Override + public void run() { + System.out.printf("%s: startup\n", getName()); + while (!this.stop) { + var blocked = true; + lock.lock(); + try { + blocked = false; + System.out.printf("%s: working\n", getName()); + Thread.sleep(8000); + } catch (InterruptedException e) { + if (blocked) { + System.out.printf("%s: blocked state interrupted\n", + getName()); + } else { + System.out.printf("%s: interrupted\n", getName()); + } + } finally { + lock.unlock(); + } + } + System.out.printf("%s: finished\n", getName()); + } + + public static void main(String... args) throws InterruptedException { + var t1 = new TaskRegular("T1"); + var t2 = new TaskRegular("T2"); + var t3 = new TaskRegular("T3"); + t1.start(); + Thread.sleep(1000); + t2.start(); + t3.start(); + t2.kill(); + t3.kill(); + t1.kill(); + t1.join(); + t2.join(); + } +} diff --git a/src/pp.06.02-LockTiming/README.md b/src/pp.06.02-LockTiming/README.md new file mode 100644 index 0000000..2b03c1f --- /dev/null +++ b/src/pp.06.02-LockTiming/README.md @@ -0,0 +1,7 @@ +# Laboraufgabe “Vergleich von ``ReentrantLock``, ``ReentrantReadWriteLock``, ``StampedLock`` und ``synchronized``” +- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-02-LockTiming.html) +- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-vergleich-von-reentrantlock-reentrantreadwritelock-stampedlock-und-synchronized") + +# Materialien +- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html) +- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html) diff --git a/src/pp.06.02-LockTiming/justfile b/src/pp.06.02-LockTiming/justfile new file mode 100644 index 0000000..0531823 --- /dev/null +++ b/src/pp.06.02-LockTiming/justfile @@ -0,0 +1,13 @@ +default: + just exec pp.ExpUnsynchronized "" + +exec class args: compile + mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}} +clean: + mvn clean +compile: + mvn compile +test: compile + mvn test +javadoc: + mvn javadoc:javadoc diff --git a/src/pp.06.02-LockTiming/pom.xml b/src/pp.06.02-LockTiming/pom.xml new file mode 100644 index 0000000..407bafd --- /dev/null +++ b/src/pp.06.02-LockTiming/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + pp + pp.06.02-LockTiming + 1.0-SNAPSHOT + jar + + + 10 + UTF-8 + + + + + projectlombok.org + https://projectlombok.org/edge-releases + + + + + + org.junit.jupiter + junit-jupiter + 5.10.0 + test + + + org.projectlombok + lombok + edge-SNAPSHOT + provided + + + net.jcip + jcip-annotations + 1.0 + provided + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.9.0 + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + private + en_US + + + + + diff --git a/src/pp.06.02-LockTiming/src/main/java/pp/ExpUnsynchronized.java b/src/pp.06.02-LockTiming/src/main/java/pp/ExpUnsynchronized.java new file mode 100644 index 0000000..fb269f8 --- /dev/null +++ b/src/pp.06.02-LockTiming/src/main/java/pp/ExpUnsynchronized.java @@ -0,0 +1,18 @@ +package pp; + +public class ExpUnsynchronized extends Experiment { + + @Override + public void incCounter() { + this.counter++; + } + + @Override + public int getCounter() { + return this.counter; + } + + public static void main(String... args) throws InterruptedException { + (new ExpUnsynchronized()).experimentPar(); + } +} diff --git a/src/pp.06.02-LockTiming/src/main/java/pp/Experiment.java b/src/pp.06.02-LockTiming/src/main/java/pp/Experiment.java new file mode 100644 index 0000000..d3e04d4 --- /dev/null +++ b/src/pp.06.02-LockTiming/src/main/java/pp/Experiment.java @@ -0,0 +1,40 @@ +package pp; + +public abstract class Experiment { + static final int WRITES = 1; // 5000 + static final int READS = 9999; // 5000 + static final int TRIALS = 100000000 / (WRITES + READS); + + protected int counter; + + public void experimentSingle() { + for (var i = 0; i < TRIALS; i++) { + for (var j = 0; j < WRITES; j++) { + incCounter(); + } + for (var j = 0; j < READS; j++) { + getCounter(); + } + } + } + + public void experimentPar() throws InterruptedException { + var t1 = new Thread(() -> experimentSingle()); + var t2 = new Thread(() -> experimentSingle()); + var now = System.currentTimeMillis(); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + System.out + .printf("Lauf %s, Zeitdauer: %dms", + (getCounter() - (2 * TRIALS * WRITES)) == 0 ? "korrekt" + : "fehlerhaft", + System.currentTimeMillis() - now); + } + + public abstract void incCounter(); + + public abstract int getCounter(); + +} diff --git a/src/pp.06.02-LockTiming_solution/README.md b/src/pp.06.02-LockTiming_solution/README.md new file mode 100644 index 0000000..2b03c1f --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/README.md @@ -0,0 +1,7 @@ +# Laboraufgabe “Vergleich von ``ReentrantLock``, ``ReentrantReadWriteLock``, ``StampedLock`` und ``synchronized``” +- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-02-LockTiming.html) +- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/06-Solutions.html#laboraufgabe-vergleich-von-reentrantlock-reentrantreadwritelock-stampedlock-und-synchronized") + +# Materialien +- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/06-locks.html) +- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/06-locks.html) diff --git a/src/pp.06.02-LockTiming_solution/justfile b/src/pp.06.02-LockTiming_solution/justfile new file mode 100644 index 0000000..6190417 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/justfile @@ -0,0 +1,16 @@ +default: + just exec pp.Main "" + +run experiment: + just exec pp.{{experiment}} "" + +exec class args: compile + mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}} +clean: + mvn clean +compile: + mvn compile +test: compile + mvn test +javadoc: + mvn javadoc:javadoc diff --git a/src/pp.06.02-LockTiming_solution/pom.xml b/src/pp.06.02-LockTiming_solution/pom.xml new file mode 100644 index 0000000..db81c90 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + pp + pp.06.02-LockTiming_solution + 1.0-SNAPSHOT + jar + + + 10 + UTF-8 + + + + + projectlombok.org + https://projectlombok.org/edge-releases + + + + + + org.junit.jupiter + junit-jupiter + 5.10.0 + test + + + org.projectlombok + lombok + edge-SNAPSHOT + provided + + + net.jcip + jcip-annotations + 1.0 + provided + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.9.0 + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + private + en_US + + + + + diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLock.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLock.java new file mode 100644 index 0000000..766fb82 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLock.java @@ -0,0 +1,43 @@ +package pp; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock;; + +public class ExpReadWriteLock extends Experiment { + private final ReadWriteLock lock; + private final Lock rLock; + private final Lock wLock; + + public ExpReadWriteLock() { + this.lock = new ReentrantReadWriteLock(false); // fair==true => (noch) + // langsamer + this.rLock = this.lock.readLock(); + this.wLock = this.lock.writeLock(); + } + + @Override + public void incCounter() { + this.wLock.lock(); + try { + this.counter++; + } finally { + this.wLock.unlock(); + } + } + + @Override + public int getCounter() { + this.rLock.lock(); + try { + return this.counter; + } finally { + this.rLock.unlock(); + } + } + + public static void main(String... args) throws InterruptedException { + (new ExpReadWriteLock()).experimentPar(); + } + +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLockLombok.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLockLombok.java new file mode 100644 index 0000000..c9ca77f --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReadWriteLockLombok.java @@ -0,0 +1,22 @@ +package pp; + +import lombok.Locked; + +public class ExpReadWriteLockLombok extends Experiment { + + @Override + @Locked.Write + public void incCounter() { + this.counter++; + } + + @Override + @Locked.Read + public int getCounter() { + return this.counter; + } + + public static void main(String... args) throws InterruptedException { + (new ExpReadWriteLock()).experimentPar(); + } +} \ No newline at end of file diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLock.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLock.java new file mode 100644 index 0000000..75f789d --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLock.java @@ -0,0 +1,36 @@ +package pp; + +import java.util.concurrent.locks.ReentrantLock; + +public class ExpReentrantLock extends Experiment { + private final ReentrantLock lock; + + public ExpReentrantLock() { + this.lock = new ReentrantLock(false); // fair==true => (noch) langsamer + } + + @Override + public void incCounter() { + this.lock.lock(); + try { + this.counter++; + } finally { + this.lock.unlock(); + } + } + + @Override + public int getCounter() { + this.lock.lock(); + try { + return this.counter; + } finally { + this.lock.unlock(); + } + } + + public static void main(String... args) throws InterruptedException { + (new ExpReentrantLock()).experimentPar(); + } + +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLockLombok.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLockLombok.java new file mode 100644 index 0000000..007c1a7 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpReentrantLockLombok.java @@ -0,0 +1,23 @@ +package pp; + +import lombok.Locked; + +public class ExpReentrantLockLombok extends Experiment { + + @Override + @Locked + public void incCounter() { + this.counter++; + } + + @Override + @Locked + public int getCounter() { + return this.counter; + } + + public static void main(String... args) throws InterruptedException { + (new ExpReentrantLock()).experimentPar(); + } + +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpStampedLock.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpStampedLock.java new file mode 100644 index 0000000..eb9e23b --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpStampedLock.java @@ -0,0 +1,42 @@ +package pp; + +import java.util.concurrent.locks.StampedLock;; + +public class ExpStampedLock extends Experiment { + private final StampedLock lock; + + public ExpStampedLock() { + this.lock = new StampedLock(); + } + + @Override + public void incCounter() { + var stamp = this.lock.writeLock(); + try { + this.counter++; + } finally { + this.lock.unlockWrite(stamp); + } + } + + @Override + public int getCounter() { + var stamp = this.lock.tryOptimisticRead(); + var result = this.counter; + if (!this.lock.validate(stamp)) { + // nicht erfolgreich + stamp = this.lock.readLock(); + try { + result = this.counter; + } finally { + this.lock.unlockRead(stamp); + } + } + return result; + } + + public static void main(String... args) throws InterruptedException { + (new ExpStampedLock()).experimentPar(); + } + +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronized.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronized.java new file mode 100644 index 0000000..4de233c --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronized.java @@ -0,0 +1,18 @@ +package pp; + +public class ExpSynchronized extends Experiment { + + @Override + public synchronized void incCounter() { + this.counter++; + } + + @Override + public synchronized int getCounter() { + return this.counter; + } + + public static void main(String... args) throws InterruptedException { + (new ExpSynchronized()).experimentPar(); + } +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronizedLombok.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronizedLombok.java new file mode 100644 index 0000000..82d0c93 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpSynchronizedLombok.java @@ -0,0 +1,22 @@ +package pp; + +import lombok.Synchronized; + +public class ExpSynchronizedLombok extends Experiment { + + @Override + @Synchronized + public void incCounter() { + this.counter++; + } + + @Override + @Synchronized + public int getCounter() { + return this.counter; + } + + public static void main(String... args) throws InterruptedException { + (new ExpSynchronized()).experimentPar(); + } +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpUnsynchronized.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpUnsynchronized.java new file mode 100644 index 0000000..fb269f8 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/ExpUnsynchronized.java @@ -0,0 +1,18 @@ +package pp; + +public class ExpUnsynchronized extends Experiment { + + @Override + public void incCounter() { + this.counter++; + } + + @Override + public int getCounter() { + return this.counter; + } + + public static void main(String... args) throws InterruptedException { + (new ExpUnsynchronized()).experimentPar(); + } +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/Experiment.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/Experiment.java new file mode 100644 index 0000000..d3e04d4 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/Experiment.java @@ -0,0 +1,40 @@ +package pp; + +public abstract class Experiment { + static final int WRITES = 1; // 5000 + static final int READS = 9999; // 5000 + static final int TRIALS = 100000000 / (WRITES + READS); + + protected int counter; + + public void experimentSingle() { + for (var i = 0; i < TRIALS; i++) { + for (var j = 0; j < WRITES; j++) { + incCounter(); + } + for (var j = 0; j < READS; j++) { + getCounter(); + } + } + } + + public void experimentPar() throws InterruptedException { + var t1 = new Thread(() -> experimentSingle()); + var t2 = new Thread(() -> experimentSingle()); + var now = System.currentTimeMillis(); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + System.out + .printf("Lauf %s, Zeitdauer: %dms", + (getCounter() - (2 * TRIALS * WRITES)) == 0 ? "korrekt" + : "fehlerhaft", + System.currentTimeMillis() - now); + } + + public abstract void incCounter(); + + public abstract int getCounter(); + +} diff --git a/src/pp.06.02-LockTiming_solution/src/main/java/pp/Main.java b/src/pp.06.02-LockTiming_solution/src/main/java/pp/Main.java new file mode 100644 index 0000000..39e9f42 --- /dev/null +++ b/src/pp.06.02-LockTiming_solution/src/main/java/pp/Main.java @@ -0,0 +1,34 @@ +package pp; + +public class Main { + + public static void main(String... args) throws InterruptedException { + System.out.print("StampedLock: "); + ExpStampedLock.main(args); + System.out.println(); + + System.out.print("ReentrantLock: "); + ExpReentrantLock.main(args); + System.out.println(); + + System.out.print("ReentrantLock (Lombok): "); + ExpReentrantLockLombok.main(args); + System.out.println(); + + System.out.print("Synchronized: "); + ExpSynchronized.main(args); + System.out.println(); + + System.out.print("Synchronized (Lombok): "); + ExpSynchronizedLombok.main(args); + System.out.println(); + + System.out.print("ReentrantReadWriteLock: "); + ExpReadWriteLock.main(args); + System.out.println(); + + System.out.print("ReentrantReadWriteLock (Lombok): "); + ExpReadWriteLockLombok.main(args); + System.out.println(); + } +}