diff --git a/src/pp.02.03-Lock/src/main/java/pp/Factory.java b/src/pp.02.03-Lock/src/main/java/pp/Factory.java
index aa9f3b8..08e2b62 100644
--- a/src/pp.02.03-Lock/src/main/java/pp/Factory.java
+++ b/src/pp.02.03-Lock/src/main/java/pp/Factory.java
@@ -3,7 +3,6 @@ package pp;
public class Factory {
private static Type instance;
- private static Object lock = new Object();
public static Type getInstance() {
Type.prepare();
diff --git a/src/pp.04.01-RunnableReturn/README.md b/src/pp.04.01-RunnableReturn/README.md
new file mode 100644
index 0000000..3fa85f7
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Thread für ``Runnable`` mit Rückgabewert"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-01-RunnableWithResult.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-Solutions.html#laboraufgabe-thread-für-runnable-mit-rückgabewert)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/04-threadpools.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/04-threadpools.html)
diff --git a/src/pp.04.01-RunnableReturn/justfile b/src/pp.04.01-RunnableReturn/justfile
new file mode 100644
index 0000000..848084f
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn/justfile
@@ -0,0 +1,12 @@
+default:
+ mvn clean compile exec:java
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.04.01-RunnableReturn/pom.xml b/src/pp.04.01-RunnableReturn/pom.xml
new file mode 100644
index 0000000..2a010e3
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ pp
+ pp.04.01-RunnableReturn
+ 1.0-SNAPSHOT
+ jar
+
+
+ pp.Main
+ 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.04.01-RunnableReturn/src/main/java/pp/Expression.java b/src/pp.04.01-RunnableReturn/src/main/java/pp/Expression.java
new file mode 100644
index 0000000..7cf3de2
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn/src/main/java/pp/Expression.java
@@ -0,0 +1,6 @@
+package pp;
+
+@FunctionalInterface
+public interface Expression {
+ public T eval();
+}
diff --git a/src/pp.04.01-RunnableReturn/src/main/java/pp/Main.java b/src/pp.04.01-RunnableReturn/src/main/java/pp/Main.java
new file mode 100644
index 0000000..c2873f8
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn/src/main/java/pp/Main.java
@@ -0,0 +1,9 @@
+package pp;
+
+public class Main {
+
+ public static void main(String... args) throws InterruptedException {
+ // hier programmieren
+ }
+
+}
diff --git a/src/pp.04.01-RunnableReturn/src/main/java/pp/RunnableWithResult.java b/src/pp.04.01-RunnableReturn/src/main/java/pp/RunnableWithResult.java
new file mode 100644
index 0000000..ec4d5d1
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn/src/main/java/pp/RunnableWithResult.java
@@ -0,0 +1,28 @@
+package pp;
+
+public class RunnableWithResult implements Runnable {
+ private final Expression expr;
+
+ public RunnableWithResult(Expression expr) {
+ this.expr = expr;
+ }
+
+ @Override
+ public void run() {
+ // hier programmieren
+ }
+
+ public synchronized Boolean isAvailable() {
+ // hier programmieren
+ return null;
+ }
+
+ public synchronized T get() {
+ // hier programmieren
+ return null;
+ }
+
+ public Expression expr() {
+ return expr;
+ }
+}
diff --git a/src/pp.04.01-RunnableReturn_solution/README.md b/src/pp.04.01-RunnableReturn_solution/README.md
new file mode 100644
index 0000000..3fa85f7
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Thread für ``Runnable`` mit Rückgabewert"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-01-RunnableWithResult.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-Solutions.html#laboraufgabe-thread-für-runnable-mit-rückgabewert)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/04-threadpools.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/04-threadpools.html)
diff --git a/src/pp.04.01-RunnableReturn_solution/justfile b/src/pp.04.01-RunnableReturn_solution/justfile
new file mode 100644
index 0000000..848084f
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/justfile
@@ -0,0 +1,12 @@
+default:
+ mvn clean compile exec:java
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.04.01-RunnableReturn_solution/pom.xml b/src/pp.04.01-RunnableReturn_solution/pom.xml
new file mode 100644
index 0000000..267481c
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ pp
+ pp.04.01-RunnableReturn_solution
+ 1.0-SNAPSHOT
+ jar
+
+
+ pp.Main
+ 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.04.01-RunnableReturn_solution/src/main/java/pp/Expression.java b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/Expression.java
new file mode 100644
index 0000000..7cf3de2
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/Expression.java
@@ -0,0 +1,6 @@
+package pp;
+
+@FunctionalInterface
+public interface Expression {
+ public T eval();
+}
diff --git a/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/Main.java b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/Main.java
new file mode 100644
index 0000000..24432cb
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/Main.java
@@ -0,0 +1,35 @@
+package pp;
+
+public class Main {
+
+ public static void main(String... args) throws InterruptedException {
+ var r1 = new RunnableWithResult2<>(() -> {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ return 1 + 2;
+ });
+ var r2 = new RunnableWithResult2<>(() -> 3 + 4);
+ var r3 = new RunnableWithResult2<>(() -> {
+ while (!r1.isAvailable() || !r2.isAvailable()) {
+ System.out.println("waiting on r1 or r2");
+ }
+ return r1.get() + r2.get();
+ });
+
+ var thread1 = new Thread(r1);
+ var thread2 = new Thread(r2);
+ var thread3 = new Thread(r3);
+
+ thread1.start();
+ thread2.start();
+ thread3.start();
+
+ while (!r3.isAvailable()) {
+ System.out.println("waiting on r3");
+ }
+ System.out.println("result: " + r3.get());
+ }
+}
diff --git a/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult.java b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult.java
new file mode 100644
index 0000000..ec4d5d1
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult.java
@@ -0,0 +1,28 @@
+package pp;
+
+public class RunnableWithResult implements Runnable {
+ private final Expression expr;
+
+ public RunnableWithResult(Expression expr) {
+ this.expr = expr;
+ }
+
+ @Override
+ public void run() {
+ // hier programmieren
+ }
+
+ public synchronized Boolean isAvailable() {
+ // hier programmieren
+ return null;
+ }
+
+ public synchronized T get() {
+ // hier programmieren
+ return null;
+ }
+
+ public Expression expr() {
+ return expr;
+ }
+}
diff --git a/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult1.java b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult1.java
new file mode 100644
index 0000000..61ced1e
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult1.java
@@ -0,0 +1,31 @@
+package pp;
+
+public class RunnableWithResult1 extends RunnableWithResult {
+ private T result;
+ private boolean finished;
+
+ public RunnableWithResult1(Expression expr) {
+ super(expr);
+ }
+
+ @Override
+ public void run() {
+ synchronized (this) { // Memorybarrier
+ this.finished = false;
+ }
+ this.result = expr().eval();
+ synchronized (this) {
+ this.finished = true;
+ } // Memorybarrier
+ }
+
+ @Override
+ public synchronized Boolean isAvailable() {
+ return this.finished;
+ }
+
+ @Override
+ public synchronized T get() {
+ return this.result;
+ }
+}
diff --git a/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult2.java b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult2.java
new file mode 100644
index 0000000..32d4190
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult2.java
@@ -0,0 +1,26 @@
+package pp;
+
+public class RunnableWithResult2 extends RunnableWithResult {
+ private T result;
+ private volatile Thread self;
+
+ public RunnableWithResult2(Expression expr) {
+ super(expr);
+ }
+
+ @Override
+ public void run() {
+ this.self = Thread.currentThread();
+ this.result = expr().eval();
+ }
+
+ @Override
+ public synchronized Boolean isAvailable() {
+ return (this.self != null) && !this.self.isAlive();
+ }
+
+ @Override
+ public synchronized T get() {
+ return this.result;
+ }
+}
diff --git a/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult3.java b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult3.java
new file mode 100644
index 0000000..ebb440b
--- /dev/null
+++ b/src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult3.java
@@ -0,0 +1,27 @@
+package pp;
+
+public class RunnableWithResult3 extends RunnableWithResult {
+ private T result;
+ private Thread executor;
+
+ public RunnableWithResult3(Expression expr) {
+ super(expr);
+ this.executor = new Thread(this);
+ this.executor.start();
+ }
+
+ @Override
+ public void run() {
+ this.result = expr().eval();
+ }
+
+ @Override
+ public synchronized Boolean isAvailable() {
+ return (this.executor != null) && !this.executor.isAlive();
+ }
+
+ @Override
+ public synchronized T get() {
+ return this.result;
+ }
+}
diff --git a/src/pp.04.02-Future/README.md b/src/pp.04.02-Future/README.md
new file mode 100644
index 0000000..bd2c085
--- /dev/null
+++ b/src/pp.04.02-Future/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Asynchrone Ausführung mit ``Callable`` und ``Future``"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-02-Future.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-Solutions.html#laboraufgabe-asynchrone-ausführung-mit-callable-und-future)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/04-threadpools.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/04-threadpools.html)
diff --git a/src/pp.04.02-Future/justfile b/src/pp.04.02-Future/justfile
new file mode 100644
index 0000000..848084f
--- /dev/null
+++ b/src/pp.04.02-Future/justfile
@@ -0,0 +1,12 @@
+default:
+ mvn clean compile exec:java
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.04.02-Future/pom.xml b/src/pp.04.02-Future/pom.xml
new file mode 100644
index 0000000..a390e40
--- /dev/null
+++ b/src/pp.04.02-Future/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ pp
+ pp.04.02-Future
+ 1.0-SNAPSHOT
+ jar
+
+
+ pp.Main
+ 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.04.02-Future/src/main/java/pp/Main.java b/src/pp.04.02-Future/src/main/java/pp/Main.java
new file mode 100644
index 0000000..429e70b
--- /dev/null
+++ b/src/pp.04.02-Future/src/main/java/pp/Main.java
@@ -0,0 +1,13 @@
+package pp;
+
+import java.util.concurrent.Executors;
+
+public class Main {
+
+ public static void main(String... args) {
+ var executor = Executors.newCachedThreadPool();
+ // hier programmieren
+ executor.shutdown();
+ }
+
+}
diff --git a/src/pp.04.02-Future_solution/README.md b/src/pp.04.02-Future_solution/README.md
new file mode 100644
index 0000000..bd2c085
--- /dev/null
+++ b/src/pp.04.02-Future_solution/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Asynchrone Ausführung mit ``Callable`` und ``Future``"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-02-Future.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-Solutions.html#laboraufgabe-asynchrone-ausführung-mit-callable-und-future)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/04-threadpools.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/04-threadpools.html)
diff --git a/src/pp.04.02-Future_solution/justfile b/src/pp.04.02-Future_solution/justfile
new file mode 100644
index 0000000..848084f
--- /dev/null
+++ b/src/pp.04.02-Future_solution/justfile
@@ -0,0 +1,12 @@
+default:
+ mvn clean compile exec:java
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.04.02-Future_solution/pom.xml b/src/pp.04.02-Future_solution/pom.xml
new file mode 100644
index 0000000..1839240
--- /dev/null
+++ b/src/pp.04.02-Future_solution/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ pp
+ pp.04.02-Future_solution
+ 1.0-SNAPSHOT
+ jar
+
+
+ pp.Main
+ 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.04.02-Future_solution/src/main/java/pp/Main.java b/src/pp.04.02-Future_solution/src/main/java/pp/Main.java
new file mode 100644
index 0000000..2174492
--- /dev/null
+++ b/src/pp.04.02-Future_solution/src/main/java/pp/Main.java
@@ -0,0 +1,34 @@
+package pp;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+
+public class Main {
+
+ public static void main(String... args) {
+ var executor = Executors.newCachedThreadPool();
+ // Lambda-Ausdruck, mehrere Statements, explizites return
+ var f1 = executor.submit(() -> {
+ return 1.0 + 2.0;
+ });
+ // Callable als Inner Class
+ var f2 = executor.submit(new Callable() {
+ @Override
+ public Double call() throws Exception {
+ return 3.0 + 4.0;
+ }
+ });
+ // Lambda-Ausdruck, knapp
+ var f3 = executor.submit(() -> f1.get() + f2.get());
+ try {
+ // get() blockiert, bis etwas vorliegt (auch oben)
+ System.out.println(f3.get());
+ } catch (InterruptedException | ExecutionException e) {
+ // Exceptions in f1 und f2 werden bis zum f3.get() verzögert
+ Thread.currentThread().interrupt();
+ } finally {
+ executor.shutdown();
+ }
+ }
+}
diff --git a/src/pp.04.03-ThreadPoolSize/README.md b/src/pp.04.03-ThreadPoolSize/README.md
new file mode 100644
index 0000000..3a03d3a
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Thread Pools"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-03-ThreadPoolSize.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-Solutions.html#laboraufgabe-thread-pools)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/04-threadpools.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/04-threadpools.html)
diff --git a/src/pp.04.03-ThreadPoolSize/justfile b/src/pp.04.03-ThreadPoolSize/justfile
new file mode 100644
index 0000000..848084f
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize/justfile
@@ -0,0 +1,12 @@
+default:
+ mvn clean compile exec:java
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.04.03-ThreadPoolSize/pom.xml b/src/pp.04.03-ThreadPoolSize/pom.xml
new file mode 100644
index 0000000..56792dd
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ pp
+ pp.04.03-ThreadPoolSize
+ 1.0-SNAPSHOT
+ jar
+
+
+ pp.Task
+ 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.04.03-ThreadPoolSize/src/main/java/pp/CachedRunner.java b/src/pp.04.03-ThreadPoolSize/src/main/java/pp/CachedRunner.java
new file mode 100644
index 0000000..ee3b654
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize/src/main/java/pp/CachedRunner.java
@@ -0,0 +1,16 @@
+package pp;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class CachedRunner {
+
+ public static ExecutorService test(Runnable task, int tries) {
+ var pool = Executors.newCachedThreadPool();
+ for (var i = 1; i <= tries; i++) {
+ pool.execute(task);
+ }
+ return pool;
+ }
+
+}
diff --git a/src/pp.04.03-ThreadPoolSize/src/main/java/pp/FixedRunner.java b/src/pp.04.03-ThreadPoolSize/src/main/java/pp/FixedRunner.java
new file mode 100644
index 0000000..ed47c09
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize/src/main/java/pp/FixedRunner.java
@@ -0,0 +1,17 @@
+package pp;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class FixedRunner {
+ private final static int SIZE = 6;
+
+ public static ExecutorService test(Runnable task, int tries) {
+ var pool = Executors.newFixedThreadPool(SIZE);
+ for (var i = 1; i <= tries; i++) {
+ pool.execute(task);
+ }
+ return pool;
+ }
+
+}
diff --git a/src/pp.04.03-ThreadPoolSize/src/main/java/pp/Task.java b/src/pp.04.03-ThreadPoolSize/src/main/java/pp/Task.java
new file mode 100644
index 0000000..132370a
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize/src/main/java/pp/Task.java
@@ -0,0 +1,17 @@
+package pp;
+
+public class Task implements Runnable {
+
+ private static final int NUMBER_OF_TASKS = 1;
+
+ @Override
+ public void run() {
+ // TODO
+ }
+
+ public static void main(String... args) {
+ // var pool = CachedRunner.test(new Task(), NUMBER_OF_TASKS);
+ var pool = FixedRunner.test(new Task(), NUMBER_OF_TASKS);
+ }
+
+}
diff --git a/src/pp.04.03-ThreadPoolSize_solution/README.md b/src/pp.04.03-ThreadPoolSize_solution/README.md
new file mode 100644
index 0000000..3a03d3a
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Thread Pools"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-03-ThreadPoolSize.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/04-Solutions.html#laboraufgabe-thread-pools)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/04-threadpools.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/04-threadpools.html)
diff --git a/src/pp.04.03-ThreadPoolSize_solution/justfile b/src/pp.04.03-ThreadPoolSize_solution/justfile
new file mode 100644
index 0000000..edbee11
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/justfile
@@ -0,0 +1,20 @@
+default:
+ mvn clean compile exec:java
+
+innerClass: (_exec "pp.TaskInnerClass" "")
+lambda: (_exec "pp.TaskLambda" "")
+staticClass: (_exec "pp.TaskStaticClass" "")
+
+_exec class args:
+ mvn exec:java -Dexec.mainClass={{class}} -Dexec.args={{args}}
+
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.04.03-ThreadPoolSize_solution/pom.xml b/src/pp.04.03-ThreadPoolSize_solution/pom.xml
new file mode 100644
index 0000000..a89caae
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ pp
+ pp.04.03-ThreadPoolSize_solution
+ 1.0-SNAPSHOT
+ jar
+
+
+ pp.TaskLambda
+ 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.04.03-ThreadPoolSize_solution/src/main/java/pp/CachedRunner.java b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/CachedRunner.java
new file mode 100644
index 0000000..ee3b654
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/CachedRunner.java
@@ -0,0 +1,16 @@
+package pp;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class CachedRunner {
+
+ public static ExecutorService test(Runnable task, int tries) {
+ var pool = Executors.newCachedThreadPool();
+ for (var i = 1; i <= tries; i++) {
+ pool.execute(task);
+ }
+ return pool;
+ }
+
+}
diff --git a/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/FixedRunner.java b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/FixedRunner.java
new file mode 100644
index 0000000..ed47c09
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/FixedRunner.java
@@ -0,0 +1,17 @@
+package pp;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class FixedRunner {
+ private final static int SIZE = 6;
+
+ public static ExecutorService test(Runnable task, int tries) {
+ var pool = Executors.newFixedThreadPool(SIZE);
+ for (var i = 1; i <= tries; i++) {
+ pool.execute(task);
+ }
+ return pool;
+ }
+
+}
diff --git a/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskInnerClass.java b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskInnerClass.java
new file mode 100644
index 0000000..3575380
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskInnerClass.java
@@ -0,0 +1,34 @@
+package pp;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class TaskInnerClass {
+
+ private static final int NUMBER_OF_TASKS = 20;
+
+ public static void main(String... args) {
+ var pool1 = FixedRunner.test(new Runnable() {
+ @Override
+ public void run() {
+ System.out.println(Thread.currentThread().getName());
+ }
+ }, NUMBER_OF_TASKS);
+ var pool2 = CachedRunner.test(new Runnable() {
+ @Override
+ public void run() {
+ System.out.println(Thread.currentThread().getName());
+ }
+ }, NUMBER_OF_TASKS);
+ var scheduler = Executors.newSingleThreadScheduledExecutor();
+ scheduler.schedule(new Runnable() {
+ @Override
+ public void run() {
+ pool1.shutdown();
+ pool2.shutdown();
+ scheduler.shutdown();
+ }
+ }, 5, TimeUnit.SECONDS);
+ }
+
+}
diff --git a/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskLambda.java b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskLambda.java
new file mode 100644
index 0000000..8420014
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskLambda.java
@@ -0,0 +1,24 @@
+package pp;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class TaskLambda {
+
+ private static final int NUMBER_OF_TASKS = 20;
+
+ public static void main(String... args) {
+ var pool1 = FixedRunner.test(
+ () -> System.out.println(Thread.currentThread().getName()),
+ NUMBER_OF_TASKS);
+ var pool2 = CachedRunner.test(
+ () -> System.out.println(Thread.currentThread().getName()),
+ NUMBER_OF_TASKS);
+ var scheduler = Executors.newSingleThreadScheduledExecutor();
+ scheduler.schedule(() -> {
+ pool1.shutdown();
+ pool2.shutdown();
+ scheduler.shutdown();
+ }, 5, TimeUnit.SECONDS);
+ }
+}
diff --git a/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskStaticClass.java b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskStaticClass.java
new file mode 100644
index 0000000..3423b7a
--- /dev/null
+++ b/src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskStaticClass.java
@@ -0,0 +1,37 @@
+package pp;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class TaskStaticClass implements Runnable {
+ static class Shutdowner implements Runnable {
+ @Override
+ public void run() {
+ pool1.shutdown();
+ pool2.shutdown();
+ scheduler.shutdown();
+ }
+ }
+
+ private static final int NUMBER_OF_TASKS = 20;
+ private static ExecutorService pool1;
+ private static ExecutorService pool2;
+ private static ScheduledExecutorService scheduler;
+
+ @Override
+ public void run() {
+ System.out.println(Thread.currentThread().getName());
+ }
+
+ public static void main(String... args) {
+ pool1 = FixedRunner.test(new TaskStaticClass(),
+ NUMBER_OF_TASKS);
+ pool2 = CachedRunner.test(new TaskStaticClass(),
+ NUMBER_OF_TASKS);
+ scheduler = Executors.newSingleThreadScheduledExecutor();
+ scheduler.schedule(new Shutdowner(), 5, TimeUnit.SECONDS);
+ }
+
+}
diff --git a/src/pp.05.01-CounterAtomic/README.md b/src/pp.05.01-CounterAtomic/README.md
new file mode 100644
index 0000000..ec96a93
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Counter mit Atomics threadsicher machen"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/05-01-CounterAtomic.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/05-Solutions.html#laboraufgabe-counter-mit-atomics-threadsicher-machen)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/05-atomics.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/05-atomics.html)
diff --git a/src/pp.05.01-CounterAtomic/justfile b/src/pp.05.01-CounterAtomic/justfile
new file mode 100644
index 0000000..43d3962
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic/justfile
@@ -0,0 +1,12 @@
+default:
+ mvn clean compile test
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.05.01-CounterAtomic/pom.xml b/src/pp.05.01-CounterAtomic/pom.xml
new file mode 100644
index 0000000..29d7273
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic/pom.xml
@@ -0,0 +1,60 @@
+
+ 4.0.0
+ pp
+ pp.05.01-CounterAtomic
+ 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.05.01-CounterAtomic/src/main/java/pp/Counter.java b/src/pp.05.01-CounterAtomic/src/main/java/pp/Counter.java
new file mode 100644
index 0000000..ce619a1
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic/src/main/java/pp/Counter.java
@@ -0,0 +1,22 @@
+package pp;
+
+class Counter {
+ private int c;
+
+ public Counter(int init) {
+ this.c = init;
+ }
+
+ public void inc() {
+ this.c++;
+ }
+
+ public void dec() {
+ this.c--;
+ }
+
+ public int get() {
+ return this.c;
+ }
+
+}
diff --git a/src/pp.05.01-CounterAtomic/src/test/java/pp/CounterTest.java b/src/pp.05.01-CounterAtomic/src/test/java/pp/CounterTest.java
new file mode 100644
index 0000000..79102d2
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic/src/test/java/pp/CounterTest.java
@@ -0,0 +1,19 @@
+package pp;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class CounterTest {
+
+ @Test
+ public void testInc() throws InterruptedException {
+ fail();
+ }
+
+ @Test
+ public void testDec() throws InterruptedException {
+ fail();
+ }
+
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/README.md b/src/pp.05.01-CounterAtomic_solution/README.md
new file mode 100644
index 0000000..ec96a93
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/README.md
@@ -0,0 +1,7 @@
+# Laboraufgabe "Counter mit Atomics threadsicher machen"
+- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/05-01-CounterAtomic.html)
+- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/05-Solutions.html#laboraufgabe-counter-mit-atomics-threadsicher-machen)
+
+# Materialien
+- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/05-atomics.html)
+- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/05-atomics.html)
diff --git a/src/pp.05.01-CounterAtomic_solution/justfile b/src/pp.05.01-CounterAtomic_solution/justfile
new file mode 100644
index 0000000..43d3962
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/justfile
@@ -0,0 +1,12 @@
+default:
+ mvn clean compile test
+exec args:
+ mvn exec:java -Dexec.args={{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test:
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
diff --git a/src/pp.05.01-CounterAtomic_solution/pom.xml b/src/pp.05.01-CounterAtomic_solution/pom.xml
new file mode 100644
index 0000000..2b5d6c9
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/pom.xml
@@ -0,0 +1,60 @@
+
+ 4.0.0
+ pp
+ pp.05.01-CounterAtomic_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.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter1.java b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter1.java
new file mode 100644
index 0000000..4d098bc
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter1.java
@@ -0,0 +1,32 @@
+package pp;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+class AtomicCounter1 implements ICounter {
+ private final AtomicInteger c;
+
+ public AtomicCounter1(int init) {
+ this.c = new AtomicInteger(init);
+ }
+
+ @Override
+ public void inc() {
+ var temp = this.c.get();
+ while (!this.c.compareAndSet(temp, temp + 1)) {
+ temp = this.c.get();
+ }
+ }
+
+ @Override
+ public void dec() {
+ var temp = this.c.get();
+ while (!this.c.compareAndSet(temp, temp - 1)) {
+ temp = this.c.get();
+ }
+ }
+
+ @Override
+ public int get() {
+ return this.c.get();
+ }
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter2.java b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter2.java
new file mode 100644
index 0000000..8aecd91
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter2.java
@@ -0,0 +1,26 @@
+package pp;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+class AtomicCounter2 implements ICounter {
+ private final AtomicInteger c;
+
+ public AtomicCounter2(int init) {
+ this.c = new AtomicInteger(init);
+ }
+
+ @Override
+ public void inc() {
+ this.c.incrementAndGet();
+ }
+
+ @Override
+ public void dec() {
+ this.c.decrementAndGet();
+ }
+
+ @Override
+ public int get() {
+ return this.c.get();
+ }
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter3.java b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter3.java
new file mode 100644
index 0000000..18b58cf
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter3.java
@@ -0,0 +1,38 @@
+package pp;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+class AtomicCounter3 implements ICounter {
+ private final AtomicInteger c;
+
+ public AtomicCounter3(int init) {
+ this.c = new AtomicInteger(init);
+ }
+
+ @Override
+ public void inc() {
+ for (;;) {
+ var current = this.c.get();
+ var next = current + 1;
+ if (this.c.compareAndSet(current, next)) {
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void dec() {
+ for (;;) {
+ var current = this.c.get();
+ var next = current - 1;
+ if (this.c.compareAndSet(current, next)) {
+ break;
+ }
+ }
+ }
+
+ @Override
+ public int get() {
+ return this.c.get();
+ }
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter4.java b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter4.java
new file mode 100644
index 0000000..04b3206
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter4.java
@@ -0,0 +1,26 @@
+package pp;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+class AtomicCounter4 implements ICounter {
+ private final AtomicInteger c;
+
+ public AtomicCounter4(int init) {
+ this.c = new AtomicInteger(init);
+ }
+
+ @Override
+ public void inc() {
+ this.c.updateAndGet(i -> i + 1);
+ }
+
+ @Override
+ public void dec() {
+ this.c.updateAndGet(i -> i - 1);
+ }
+
+ @Override
+ public int get() {
+ return this.c.get();
+ }
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/Counter.java b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/Counter.java
new file mode 100644
index 0000000..fc83ae7
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/Counter.java
@@ -0,0 +1,24 @@
+package pp;
+
+class Counter implements ICounter {
+ private int c;
+
+ public Counter(int init) {
+ this.c = init;
+ }
+
+ @Override
+ public void inc() {
+ this.c++;
+ }
+
+ @Override
+ public void dec() {
+ this.c--;
+ }
+
+ @Override
+ public int get() {
+ return this.c;
+ }
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/ICounter.java b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/ICounter.java
new file mode 100644
index 0000000..18b4caa
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/ICounter.java
@@ -0,0 +1,11 @@
+package pp;
+
+interface ICounter {
+
+ void inc();
+
+ void dec();
+
+ int get();
+
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/SynchronizedCounter.java b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/SynchronizedCounter.java
new file mode 100644
index 0000000..050cf46
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/main/java/pp/SynchronizedCounter.java
@@ -0,0 +1,24 @@
+package pp;
+
+class SynchronizedCounter implements ICounter {
+ private int c;
+
+ public SynchronizedCounter(int init) {
+ this.c = init;
+ }
+
+ @Override
+ public synchronized void inc() {
+ this.c++;
+ }
+
+ @Override
+ public synchronized void dec() {
+ this.c--;
+ }
+
+ @Override
+ public synchronized int get() {
+ return this.c;
+ }
+}
diff --git a/src/pp.05.01-CounterAtomic_solution/src/test/java/pp/CounterTest.java b/src/pp.05.01-CounterAtomic_solution/src/test/java/pp/CounterTest.java
new file mode 100644
index 0000000..c791d09
--- /dev/null
+++ b/src/pp.05.01-CounterAtomic_solution/src/test/java/pp/CounterTest.java
@@ -0,0 +1,116 @@
+package pp;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+class CounterTest {
+ private final static int RUNS = 500000;
+
+ private static void testIncrement(ICounter counter) {
+ assertEquals(0, counter.get());
+ var t1 = new Thread(() -> {
+ for (var j = 0; j < RUNS; j++) {
+ counter.inc();
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var j = 0; j < RUNS; j++) {
+ counter.inc();
+ }
+ });
+ t1.start();
+ t2.start();
+ try {
+ t1.join();
+ t2.join();
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ assertEquals(RUNS * 2, counter.get());
+ }
+
+ @Test
+ void testCounterIncrement() throws InterruptedException {
+ testIncrement(new Counter(0));
+ }
+
+ @Test
+ void testSynchronizedCounterIncrement() throws InterruptedException {
+ testIncrement(new SynchronizedCounter(0));
+ }
+
+ @Test
+ void testAtomicCounter1Increment() throws InterruptedException {
+ testIncrement(new AtomicCounter1(0));
+ }
+
+ @Test
+ void testAtomicCounter2Increment() throws InterruptedException {
+ testIncrement(new AtomicCounter2(0));
+ }
+
+ @Test
+ void testAtomicCounter3Increment() throws InterruptedException {
+ testIncrement(new AtomicCounter3(0));
+ }
+
+ @Test
+ void testAtomicCounter4Increment() throws InterruptedException {
+ testIncrement(new AtomicCounter4(0));
+ }
+
+ private static void testDecrement(ICounter counter) {
+ assertEquals(RUNS * 2, counter.get());
+ var t1 = new Thread(() -> {
+ for (var j = 0; j < RUNS; j++) {
+ counter.dec();
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var j = 0; j < RUNS; j++) {
+ counter.dec();
+ }
+ });
+ t1.start();
+ t2.start();
+ try {
+ t1.join();
+ t2.join();
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ assertEquals(0, counter.get());
+ }
+
+ @Test
+ void testCounterDecrement() throws InterruptedException {
+ testDecrement(new Counter(RUNS * 2));
+ }
+
+ @Test
+ void testSynchronizedCounterDecrement() throws InterruptedException {
+ testDecrement(new SynchronizedCounter(RUNS * 2));
+ }
+
+ @Test
+ void testAtomicCounter1Decrement() throws InterruptedException {
+ testDecrement(new AtomicCounter1(RUNS * 2));
+ }
+
+ @Test
+ void testAtomicCounter2Decrement() throws InterruptedException {
+ testDecrement(new AtomicCounter2(RUNS * 2));
+ }
+
+ @Test
+ void testAtomicCounter3Decrement() throws InterruptedException {
+ testDecrement(new AtomicCounter3(RUNS * 2));
+ }
+
+ @Test
+ void testAtomicCounter4Decrement() throws InterruptedException {
+ testDecrement(new AtomicCounter4(RUNS * 2));
+ }
+
+}