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();
+ }
+}