Add structured-concurrency-final module: StructuredTaskScope final in JDK 28 (JEP 543), run on 28-ea, 27, 26 and 25

Runnable demos for the ankurm.com structured-concurrency-java article: the ExecutorService thread leak and its fix, every built-in Joiner,
structure violations, timeouts, a custom Joiner, JSON thread dumps (in-process and jcmd), scoped values, javap diffs of the API on 25, 26, 27 and 28-ea,
compiler output for six pieces of 25/26-era code, and the preview class-file trap between 27 and 28. Transcripts in output/.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CifR2BE7PBvRy5hT8TS9oz
This commit is contained in:
Claude
2026-10-26 02:01:31 +00:00
parent 2e25042a68
commit c93a1fffbb
37 changed files with 1351 additions and 0 deletions
@@ -0,0 +1,74 @@
$ diff api-25 api-26 (signature lines only; the first line of each file names the build)
< public static <T, R> StructuredTaskScope<T, R> open(StructuredTaskScope$Joiner<? super T, ? extends R>, Function<StructuredTaskScope$Configuration, StructuredTaskScope$Configuration>);
> public static <T, R> StructuredTaskScope<T, R> open(StructuredTaskScope$Joiner<? super T, ? extends R>, UnaryOperator<StructuredTaskScope$Configuration>);
< public default boolean onFork(StructuredTaskScope$Subtask<? extends T>);
< public default boolean onComplete(StructuredTaskScope$Subtask<? extends T>);
> public default boolean onFork(StructuredTaskScope$Subtask<T>);
> public default boolean onComplete(StructuredTaskScope$Subtask<T>);
> public default void onTimeout();
< public static <T> StructuredTaskScope$Joiner<T, stream.Stream<StructuredTaskScope$Subtask<T>>> allSuccessfulOrThrow();
< public static <T> StructuredTaskScope$Joiner<T, T> anySuccessfulResultOrThrow();
> public static <T> StructuredTaskScope$Joiner<T, List<T>> allSuccessfulOrThrow();
> public static <T> StructuredTaskScope$Joiner<T, T> anySuccessfulOrThrow();
< public static <T> StructuredTaskScope$Joiner<T, stream.Stream<StructuredTaskScope$Subtask<T>>> allUntil(Predicate<StructuredTaskScope$Subtask<? extends T>>);
> public static <T> StructuredTaskScope$Joiner<T, List<StructuredTaskScope$Subtask<T>>> allUntil(Predicate<StructuredTaskScope$Subtask<T>>);
$ diff api-26 api-27 (signature lines only; the first line of each file names the build)
< public interface StructuredTaskScope<T, R> extends AutoCloseable {
< public static <T, R> StructuredTaskScope<T, R> open(StructuredTaskScope$Joiner<? super T, ? extends R>, UnaryOperator<StructuredTaskScope$Configuration>);
< public static <T, R> StructuredTaskScope<T, R> open(StructuredTaskScope$Joiner<? super T, ? extends R>);
< public static <T> StructuredTaskScope<T, Void> open();
> public interface StructuredTaskScope<T, R, R_X extends Throwable> extends AutoCloseable {
> public static <T, R, R_X extends Throwable> StructuredTaskScope<T, R, R_X> open(StructuredTaskScope$Joiner<? super T, ? extends R, R_X>, UnaryOperator<StructuredTaskScope$Configuration>);
> public static <T, R, R_X extends Throwable> StructuredTaskScope<T, R, R_X> open(StructuredTaskScope$Joiner<? super T, ? extends R, R_X>);
> public static <T> StructuredTaskScope<T, Void, ExecutionException> open(UnaryOperator<StructuredTaskScope$Configuration>);
> public static <T> StructuredTaskScope<T, Void, ExecutionException> open();
< public abstract R join() throws InterruptedException;
> public abstract R join() throws R_X, InterruptedException;
< public interface StructuredTaskScope$Joiner<T, R> {
> public interface StructuredTaskScope$Joiner<T, R, R_X extends Throwable> {
< public default void onTimeout();
< public abstract R result() throws Throwable;
< public static <T> StructuredTaskScope$Joiner<T, List<T>> allSuccessfulOrThrow();
< public static <T> StructuredTaskScope$Joiner<T, T> anySuccessfulOrThrow();
< public static <T> StructuredTaskScope$Joiner<T, Void> awaitAllSuccessfulOrThrow();
< public static <T> StructuredTaskScope$Joiner<T, Void> awaitAll();
< public static <T> StructuredTaskScope$Joiner<T, List<StructuredTaskScope$Subtask<T>>> allUntil(Predicate<StructuredTaskScope$Subtask<T>>);
> public abstract R result() throws R_X;
> public abstract R timeout() throws R_X;
> public static <T, R_X extends Throwable> StructuredTaskScope$Joiner<T, List<T>, R_X> allSuccessfulOrThrow(Function<Throwable, R_X>);
> public static <T> StructuredTaskScope$Joiner<T, List<T>, ExecutionException> allSuccessfulOrThrow();
> public static <T, R_X extends Throwable> StructuredTaskScope$Joiner<T, T, R_X> anySuccessfulOrThrow(Function<Throwable, R_X>);
> public static <T> StructuredTaskScope$Joiner<T, T, ExecutionException> anySuccessfulOrThrow();
> public static <T, R_X extends Throwable> StructuredTaskScope$Joiner<T, Void, R_X> awaitAllSuccessfulOrThrow(Function<Throwable, R_X>);
> public static <T> StructuredTaskScope$Joiner<T, Void, ExecutionException> awaitAllSuccessfulOrThrow();
> public static <T> StructuredTaskScope$Joiner<T, List<StructuredTaskScope$Subtask<T>>, RuntimeException> allUntil(Predicate<? super StructuredTaskScope$Subtask<T>>);
$ diff api-27 api-28 (signature lines only; the first line of each file names the build)
(no difference)
$ jimage list modules | grep -E 'FailedException|TimeoutException|CancelledByTimeout' (25.0.5+8-LTS)
java/util/concurrent/StructuredTaskScope$FailedException.class
java/util/concurrent/StructuredTaskScope$TimeoutException.class
$ jimage list modules | grep -E 'FailedException|TimeoutException|CancelledByTimeout' (26.0.2.1+1)
java/util/concurrent/StructuredTaskScope$FailedException.class
java/util/concurrent/StructuredTaskScope$TimeoutException.class
$ jimage list modules | grep -E 'FailedException|TimeoutException|CancelledByTimeout' (27.0.1.0.2+1)
java/util/concurrent/StructuredTaskScope$CancelledByTimeoutException.class
$ jimage list modules | grep -E 'FailedException|TimeoutException|CancelledByTimeout' (28-beta+21-ea)
java/util/concurrent/StructuredTaskScope$CancelledByTimeoutException.class
$ javap -v StructuredTaskScope | grep 'PreviewFeature(' -A1 (26.0.2.1+1)
jdk.internal.javac.PreviewFeature(
feature=Ljdk/internal/javac/PreviewFeature$Feature;.STRUCTURED_CONCURRENCY
$ javap -v StructuredTaskScope | grep 'PreviewFeature(' -A1 (27.0.1.0.2+1)
jdk.internal.javac.PreviewFeature(
feature=Ljdk/internal/javac/PreviewFeature$Feature;.STRUCTURED_CONCURRENCY
$ javap -v StructuredTaskScope | grep 'PreviewFeature(' -A1 (28-beta+21-ea)
(no @PreviewFeature annotation: the API is final)