diff --git a/src/pp.09.02-StructuredConcurrency/justfile b/src/pp.09.02-StructuredConcurrency/justfile
new file mode 100644
index 0000000..847ca9b
--- /dev/null
+++ b/src/pp.09.02-StructuredConcurrency/justfile
@@ -0,0 +1,21 @@
+# Justfile (https://just.systems/) for starting Maven standard targets
+
+default: clean compile
+ #!/usr/bin/env bash
+ cd target/classes
+ java --enable-preview pp.Exec
+
+exec class args: compile
+ mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
+# exec class args:
+# java -cp target/app.jar {{class}} {{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test: compile
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
+package:
+ mvn package
diff --git a/src/pp.09.02-StructuredConcurrency/pom.xml b/src/pp.09.02-StructuredConcurrency/pom.xml
new file mode 100644
index 0000000..6f3a9d7
--- /dev/null
+++ b/src/pp.09.02-StructuredConcurrency/pom.xml
@@ -0,0 +1,77 @@
+
+ 4.0.0
+ pp
+ pp.09.02-StructuredConcurrency
+ 1.0-SNAPSHOT
+ jar
+
+
+ 23
+ edge-SNAPSHOT
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.0
+ test
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+ net.jcip
+ jcip-annotations
+ 1.0
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0
+
+ --enable-preview
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.9.0
+
+ --enable-preview
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+ --enable-preview
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+ private
+ en_US
+
+
+
+
+
diff --git a/src/pp.09.02-StructuredConcurrency/pom_.xml b/src/pp.09.02-StructuredConcurrency/pom_.xml
new file mode 100644
index 0000000..ffbd7b2
--- /dev/null
+++ b/src/pp.09.02-StructuredConcurrency/pom_.xml
@@ -0,0 +1,84 @@
+
+ 4.0.0
+ pp
+ pp.09.02-StructuredConcurrency
+ 1.0-SNAPSHOT
+ jar
+
+
+ 21
+ edge-SNAPSHOT
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.0
+ test
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ 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.11.0
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+ --enable-preview
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+ java
+
+ -classpath
+ target/classes
+ --enable-preview
+ io.dama.ffi.structconc.Exec
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+ private
+ en_US
+
+
+
+
+
diff --git a/src/pp.09.02-StructuredConcurrency/src/main/java/pp/Exec.java b/src/pp.09.02-StructuredConcurrency/src/main/java/pp/Exec.java
new file mode 100644
index 0000000..65c67f5
--- /dev/null
+++ b/src/pp.09.02-StructuredConcurrency/src/main/java/pp/Exec.java
@@ -0,0 +1,31 @@
+package pp;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.StructuredTaskScope;
+
+public class Exec {
+ static T race(List> tasks) throws InterruptedException, ExecutionException {
+ try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) {
+ for (var task : tasks) {
+ scope.fork(task);
+ }
+ return scope.join().result();
+ }
+ }
+
+ public static void main(String... args)
+ throws InterruptedException, TimeoutException, Throwable {
+ var tasks = new ArrayList>();
+ for (var i = 0; i < Runtime.getRuntime().availableProcessors() - 1; i++) {
+ tasks.add(() -> BigInteger.probablePrime(2048, ThreadLocalRandom.current()));
+ }
+ System.out.println(race(tasks));
+ }
+
+}