From 31710c55ea1903d48468fe1dedb551e7ef2cd359 Mon Sep 17 00:00:00 2001 From: Sandro Leuchter Date: Wed, 16 Oct 2024 10:26:05 +0200 Subject: [PATCH 1/3] Kap. 4 --- src/pp.04.01-RunnableReturn/justfile | 12 ++++ src/pp.04.01-RunnableReturn/pom.xml | 61 +++++++++++++++++++ .../src/main/java/pp/Expression.java | 6 ++ .../src/main/java/pp/Main.java | 9 +++ .../src/main/java/pp/RunnableWithResult.java | 28 +++++++++ src/pp.04.01-RunnableReturn_solution/justfile | 12 ++++ src/pp.04.01-RunnableReturn_solution/pom.xml | 61 +++++++++++++++++++ .../src/main/java/pp/Expression.java | 6 ++ .../src/main/java/pp/Main.java | 35 +++++++++++ .../src/main/java/pp/RunnableWithResult.java | 28 +++++++++ .../src/main/java/pp/RunnableWithResult1.java | 31 ++++++++++ .../src/main/java/pp/RunnableWithResult2.java | 26 ++++++++ .../src/main/java/pp/RunnableWithResult3.java | 27 ++++++++ src/pp.04.02-Future/justfile | 12 ++++ src/pp.04.02-Future/pom.xml | 61 +++++++++++++++++++ .../src/main/java/pp/Main.java | 13 ++++ src/pp.04.02-Future_solution/justfile | 12 ++++ src/pp.04.02-Future_solution/pom.xml | 61 +++++++++++++++++++ .../src/main/java/pp/Main.java | 34 +++++++++++ src/pp.04.03-ThreadPoolSize/justfile | 12 ++++ src/pp.04.03-ThreadPoolSize/pom.xml | 61 +++++++++++++++++++ .../src/main/java/pp/CachedRunner.java | 16 +++++ .../src/main/java/pp/FixedRunner.java | 17 ++++++ .../src/main/java/pp/Task.java | 17 ++++++ src/pp.04.03-ThreadPoolSize_solution/justfile | 20 ++++++ src/pp.04.03-ThreadPoolSize_solution/pom.xml | 61 +++++++++++++++++++ .../src/main/java/pp/CachedRunner.java | 16 +++++ .../src/main/java/pp/FixedRunner.java | 17 ++++++ .../src/main/java/pp/TaskInnerClass.java | 34 +++++++++++ .../src/main/java/pp/TaskLambda.java | 24 ++++++++ .../src/main/java/pp/TaskStaticClass.java | 37 +++++++++++ 31 files changed, 867 insertions(+) create mode 100644 src/pp.04.01-RunnableReturn/justfile create mode 100644 src/pp.04.01-RunnableReturn/pom.xml create mode 100644 src/pp.04.01-RunnableReturn/src/main/java/pp/Expression.java create mode 100644 src/pp.04.01-RunnableReturn/src/main/java/pp/Main.java create mode 100644 src/pp.04.01-RunnableReturn/src/main/java/pp/RunnableWithResult.java create mode 100644 src/pp.04.01-RunnableReturn_solution/justfile create mode 100644 src/pp.04.01-RunnableReturn_solution/pom.xml create mode 100644 src/pp.04.01-RunnableReturn_solution/src/main/java/pp/Expression.java create mode 100644 src/pp.04.01-RunnableReturn_solution/src/main/java/pp/Main.java create mode 100644 src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult.java create mode 100644 src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult1.java create mode 100644 src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult2.java create mode 100644 src/pp.04.01-RunnableReturn_solution/src/main/java/pp/RunnableWithResult3.java create mode 100644 src/pp.04.02-Future/justfile create mode 100644 src/pp.04.02-Future/pom.xml create mode 100644 src/pp.04.02-Future/src/main/java/pp/Main.java create mode 100644 src/pp.04.02-Future_solution/justfile create mode 100644 src/pp.04.02-Future_solution/pom.xml create mode 100644 src/pp.04.02-Future_solution/src/main/java/pp/Main.java create mode 100644 src/pp.04.03-ThreadPoolSize/justfile create mode 100644 src/pp.04.03-ThreadPoolSize/pom.xml create mode 100644 src/pp.04.03-ThreadPoolSize/src/main/java/pp/CachedRunner.java create mode 100644 src/pp.04.03-ThreadPoolSize/src/main/java/pp/FixedRunner.java create mode 100644 src/pp.04.03-ThreadPoolSize/src/main/java/pp/Task.java create mode 100644 src/pp.04.03-ThreadPoolSize_solution/justfile create mode 100644 src/pp.04.03-ThreadPoolSize_solution/pom.xml create mode 100644 src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/CachedRunner.java create mode 100644 src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/FixedRunner.java create mode 100644 src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskInnerClass.java create mode 100644 src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskLambda.java create mode 100644 src/pp.04.03-ThreadPoolSize_solution/src/main/java/pp/TaskStaticClass.java 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/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/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/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/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/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); + } + +} From 79c516f4f445b2b71ab0bd564cf1cbf008b09569 Mon Sep 17 00:00:00 2001 From: Sandro Leuchter Date: Wed, 16 Oct 2024 23:20:23 +0200 Subject: [PATCH 2/3] N/A --- src/pp.02.03-Lock/src/main/java/pp/Factory.java | 1 - 1 file changed, 1 deletion(-) 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(); From 08037aa59509bc3c52936f733fb325a94b52c0fd Mon Sep 17 00:00:00 2001 From: Sandro Leuchter Date: Thu, 24 Oct 2024 00:11:25 +0200 Subject: [PATCH 3/3] initial --- src/pp.04.01-RunnableReturn/README.md | 7 ++ .../README.md | 7 ++ src/pp.04.02-Future/README.md | 7 ++ src/pp.04.02-Future_solution/README.md | 7 ++ src/pp.04.03-ThreadPoolSize/README.md | 7 ++ .../README.md | 7 ++ src/pp.05.01-CounterAtomic/README.md | 7 ++ src/pp.05.01-CounterAtomic/justfile | 12 ++ src/pp.05.01-CounterAtomic/pom.xml | 60 +++++++++ .../src/main/java/pp/Counter.java | 22 ++++ .../src/test/java/pp/CounterTest.java | 19 +++ src/pp.05.01-CounterAtomic_solution/README.md | 7 ++ src/pp.05.01-CounterAtomic_solution/justfile | 12 ++ src/pp.05.01-CounterAtomic_solution/pom.xml | 60 +++++++++ .../src/main/java/pp/AtomicCounter1.java | 32 +++++ .../src/main/java/pp/AtomicCounter2.java | 26 ++++ .../src/main/java/pp/AtomicCounter3.java | 38 ++++++ .../src/main/java/pp/AtomicCounter4.java | 26 ++++ .../src/main/java/pp/Counter.java | 24 ++++ .../src/main/java/pp/ICounter.java | 11 ++ .../src/main/java/pp/SynchronizedCounter.java | 24 ++++ .../src/test/java/pp/CounterTest.java | 116 ++++++++++++++++++ 22 files changed, 538 insertions(+) create mode 100644 src/pp.04.01-RunnableReturn/README.md create mode 100644 src/pp.04.01-RunnableReturn_solution/README.md create mode 100644 src/pp.04.02-Future/README.md create mode 100644 src/pp.04.02-Future_solution/README.md create mode 100644 src/pp.04.03-ThreadPoolSize/README.md create mode 100644 src/pp.04.03-ThreadPoolSize_solution/README.md create mode 100644 src/pp.05.01-CounterAtomic/README.md create mode 100644 src/pp.05.01-CounterAtomic/justfile create mode 100644 src/pp.05.01-CounterAtomic/pom.xml create mode 100644 src/pp.05.01-CounterAtomic/src/main/java/pp/Counter.java create mode 100644 src/pp.05.01-CounterAtomic/src/test/java/pp/CounterTest.java create mode 100644 src/pp.05.01-CounterAtomic_solution/README.md create mode 100644 src/pp.05.01-CounterAtomic_solution/justfile create mode 100644 src/pp.05.01-CounterAtomic_solution/pom.xml create mode 100644 src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter1.java create mode 100644 src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter2.java create mode 100644 src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter3.java create mode 100644 src/pp.05.01-CounterAtomic_solution/src/main/java/pp/AtomicCounter4.java create mode 100644 src/pp.05.01-CounterAtomic_solution/src/main/java/pp/Counter.java create mode 100644 src/pp.05.01-CounterAtomic_solution/src/main/java/pp/ICounter.java create mode 100644 src/pp.05.01-CounterAtomic_solution/src/main/java/pp/SynchronizedCounter.java create mode 100644 src/pp.05.01-CounterAtomic_solution/src/test/java/pp/CounterTest.java 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_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.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_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.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_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.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)); + } + +}