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:
@@ -0,0 +1,35 @@
|
||||
$ javac src/Server.java && java Server (28-beta+21-ea)
|
||||
Response[user=Alice, order=42]
|
||||
Runtime: 28-beta+21-ea
|
||||
|
||||
$ javac --enable-preview --release 27 src/Server.java && java --enable-preview Server (27.0.1.0.2+1)
|
||||
Response[user=Alice, order=42]
|
||||
Runtime: 27.0.1.0.2+1
|
||||
|
||||
$ javac src/Server.java (27.0.1.0.2+1)
|
||||
src/Server.java:2: error: StructuredTaskScope is a preview API and is disabled by default.
|
||||
import java.util.concurrent.StructuredTaskScope;
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:3: error: StructuredTaskScope is a preview API and is disabled by default.
|
||||
import java.util.concurrent.StructuredTaskScope.Subtask;
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:3: error: Subtask is a preview API and is disabled by default.
|
||||
import java.util.concurrent.StructuredTaskScope.Subtask;
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:22: error: StructuredTaskScope is a preview API and is disabled by default.
|
||||
try (var scope = StructuredTaskScope.open()) { // 1. open
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:23: error: Subtask is a preview API and is disabled by default.
|
||||
Subtask<String> user = scope.fork(this::findUser); // 2. fork
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:24: error: Subtask is a preview API and is disabled by default.
|
||||
Subtask<Integer> order = scope.fork(this::fetchOrder); // fork
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
6 errors
|
||||
exit=1
|
||||
@@ -0,0 +1,10 @@
|
||||
$ javac src/Unstructured.java && java Unstructured (28-beta+21-ea)
|
||||
handle() failed: java.lang.IllegalStateException: user service down
|
||||
handle() has returned. Waiting 400 ms to see what the other thread does:
|
||||
fetchOrder() finished, although nobody wants the answer any more
|
||||
|
||||
$ javac src/FailFast.java && java FailFast (28-beta+21-ea)
|
||||
fetchOrder() was interrupted
|
||||
handle() failed: java.lang.IllegalStateException: user service down
|
||||
handle() has returned. Waiting 400 ms to see what the other thread does:
|
||||
(nothing more happened)
|
||||
@@ -0,0 +1,21 @@
|
||||
$ javac src/Joiners.java && java Joiners (28-beta+21-ea)
|
||||
-- allSuccessfulOrThrow(): List in FORK order, not completion order
|
||||
[slow, fast, medium]
|
||||
-- allSuccessfulOrThrow(): one failure cancels the others, join() throws ExecutionException
|
||||
ExecutionException, cause = java.lang.IllegalStateException: broken failed
|
||||
interrupted: [slow]
|
||||
-- anySuccessfulOrThrow(): the race; losers are interrupted
|
||||
winner: B-50ms
|
||||
interrupted: [A-300ms, C-300ms]
|
||||
-- anySuccessfulOrThrow(): when every subtask fails
|
||||
ExecutionException, cause = java.lang.IllegalStateException: one failed
|
||||
-- awaitAllSuccessfulOrThrow(): returns null (Void), like the zero-argument open()
|
||||
join() = null, a=a, b=b
|
||||
-- allUntil(predicate): stop when two subtasks have completed
|
||||
SUCCESS t1
|
||||
SUCCESS t2
|
||||
UNAVAILABLE
|
||||
UNAVAILABLE
|
||||
interrupted: [t3, t4]
|
||||
-- the Function overload: join() throws OUR exception type
|
||||
caught ServiceException: service call failed: orders failed
|
||||
@@ -0,0 +1,15 @@
|
||||
$ javac src/Failures.java && java Failures (28-beta+21-ea)
|
||||
-- Subtask.get() before join()
|
||||
java.lang.IllegalStateException: null
|
||||
-- leaving the try block without join()
|
||||
java.lang.IllegalStateException: Owner did not join after forking
|
||||
-- fork() from a thread that does not own the scope
|
||||
returned java.lang.WrongThreadException: Current thread not owner
|
||||
-- closing scopes out of order (not try-with-resources)
|
||||
java.util.concurrent.StructureViolationException: null
|
||||
-- join() twice
|
||||
java.lang.IllegalStateException: Already joined or scope is closed
|
||||
-- the failure surfaces as ExecutionException; pattern-match the cause
|
||||
I/O failed: disk gone
|
||||
-- two subtasks fail: which cause do you get?
|
||||
cause = first (the first to fail wins)
|
||||
@@ -0,0 +1,15 @@
|
||||
$ javac src/Timeouts.java && java Timeouts (28-beta+21-ea)
|
||||
-- inside the deadline
|
||||
[fast, fast]
|
||||
-- deadline 200 ms, one subtask needs 5 s
|
||||
ExecutionException, cause = java.util.concurrent.StructuredTaskScope$CancelledByTimeoutException
|
||||
returned within well under a second (not 5 s): the slow subtask was interrupted
|
||||
-- the same deadline with a joiner whose timeout() returns a partial result
|
||||
join() = [fast]
|
||||
-- a thread factory decides the subtask thread's name
|
||||
[order-0, order-1]
|
||||
|
||||
$ javac src/CollectingJoiner.java && java CollectingJoiner (28-beta+21-ea)
|
||||
collected (sorted): [1, 3]
|
||||
-- with a 100 ms timeout and a 5 s subtask
|
||||
CompletionException, cause = java.util.concurrent.StructuredTaskScope$CancelledByTimeoutException
|
||||
@@ -0,0 +1,12 @@
|
||||
$ javac src/ThreadDump.java && java ThreadDump (28-beta+21-ea)
|
||||
"container": "orders\/jdk.internal.misc.ThreadFlock$ThreadContainerImpl@<hash>",
|
||||
"parent": "<root>",
|
||||
"owner": <n>,
|
||||
"tid": <n>,
|
||||
"virtual": true,
|
||||
"state": "TIMED_WAITING",
|
||||
"ThreadDump.lambda$main$6(ThreadDump.java:28)",
|
||||
"tid": <n>,
|
||||
"virtual": true,
|
||||
"state": "TIMED_WAITING",
|
||||
"ThreadDump.lambda$main$6(ThreadDump.java:28)",
|
||||
@@ -0,0 +1,4 @@
|
||||
$ javac src/ScopedValues.java && java ScopedValues (28-beta+21-ea)
|
||||
forked subtask sees req-7731
|
||||
plain thread: bound? false
|
||||
outside the binding: bound? false
|
||||
@@ -0,0 +1,48 @@
|
||||
# javap java.util.concurrent.StructuredTaskScope and its nested types (28-beta+21-ea)
|
||||
Compiled from "StructuredTaskScope.java"
|
||||
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 <U extends T> StructuredTaskScope$Subtask<U> fork(Callable<? extends U>);
|
||||
public abstract <U extends T> StructuredTaskScope$Subtask<U> fork(Runnable);
|
||||
public abstract R join() throws R_X, InterruptedException;
|
||||
public abstract boolean isCancelled();
|
||||
public abstract void close();
|
||||
}
|
||||
Compiled from "StructuredTaskScope.java"
|
||||
public interface StructuredTaskScope$Joiner<T, R, R_X extends Throwable> {
|
||||
public default boolean onFork(StructuredTaskScope$Subtask<T>);
|
||||
public default boolean onComplete(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>>);
|
||||
}
|
||||
Compiled from "StructuredTaskScope.java"
|
||||
public interface StructuredTaskScope$Configuration {
|
||||
public abstract StructuredTaskScope$Configuration withThreadFactory(ThreadFactory);
|
||||
public abstract StructuredTaskScope$Configuration withName(String);
|
||||
public abstract StructuredTaskScope$Configuration withTimeout(java.time.Duration);
|
||||
}
|
||||
Compiled from "StructuredTaskScope.java"
|
||||
public interface StructuredTaskScope$Subtask<T> extends Supplier<T> {
|
||||
public abstract StructuredTaskScope$Subtask$State state();
|
||||
public abstract T get();
|
||||
public abstract Throwable exception();
|
||||
}
|
||||
Compiled from "StructuredTaskScope.java"
|
||||
public final class StructuredTaskScope$Subtask$State extends Enum<StructuredTaskScope$Subtask$State> {
|
||||
public static final StructuredTaskScope$Subtask$State UNAVAILABLE;
|
||||
public static final StructuredTaskScope$Subtask$State SUCCESS;
|
||||
public static final StructuredTaskScope$Subtask$State FAILED;
|
||||
public static StructuredTaskScope$Subtask$State[] values();
|
||||
public static StructuredTaskScope$Subtask$State valueOf(String);
|
||||
static {};
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
$ javac --enable-preview --release 26 broken/MissingCatch.java (26.0.2.1+1)
|
||||
exit=0
|
||||
|
||||
$ javac broken/MissingCatch.java (28-beta+21-ea)
|
||||
broken/MissingCatch.java:8: error: unreported exception ExecutionException; must be caught or declared to be thrown
|
||||
scope.join();
|
||||
^
|
||||
1 error
|
||||
exit=1
|
||||
|
||||
$ javac --enable-preview --release 26 broken/OldFailedException.java (26.0.2.1+1)
|
||||
exit=0
|
||||
|
||||
$ javac broken/OldFailedException.java (28-beta+21-ea)
|
||||
broken/OldFailedException.java:9: error: cannot find symbol
|
||||
} catch (StructuredTaskScope.FailedException e) {
|
||||
^
|
||||
symbol: class FailedException
|
||||
location: interface StructuredTaskScope
|
||||
1 error
|
||||
exit=1
|
||||
|
||||
$ javac --enable-preview --release 26 broken/OldTimeoutException.java (26.0.2.1+1)
|
||||
exit=0
|
||||
|
||||
$ javac broken/OldTimeoutException.java (28-beta+21-ea)
|
||||
broken/OldTimeoutException.java:11: error: cannot find symbol
|
||||
} catch (StructuredTaskScope.TimeoutException e) {
|
||||
^
|
||||
symbol: class TimeoutException
|
||||
location: interface StructuredTaskScope
|
||||
1 error
|
||||
exit=1
|
||||
|
||||
$ javac --enable-preview --release 26 broken/AwaitAll.java (26.0.2.1+1)
|
||||
exit=0
|
||||
|
||||
$ javac broken/AwaitAll.java (28-beta+21-ea)
|
||||
broken/AwaitAll.java:7: error: cannot find symbol
|
||||
try (var scope = StructuredTaskScope.open(Joiner.<String>awaitAll())) {
|
||||
^
|
||||
symbol: method <String>awaitAll()
|
||||
location: interface Joiner
|
||||
1 error
|
||||
exit=1
|
||||
|
||||
$ javac --enable-preview --release 26 broken/OldJoiner.java (26.0.2.1+1)
|
||||
exit=0
|
||||
|
||||
$ javac broken/OldJoiner.java (28-beta+21-ea)
|
||||
broken/OldJoiner.java:7: error: wrong number of type arguments; required 3
|
||||
public class OldJoiner<T> implements Joiner<T, List<T>> {
|
||||
^
|
||||
1 error
|
||||
exit=1
|
||||
|
||||
$ javac --enable-preview --release 26 broken/ShutdownOnFailure.java (26.0.2.1+1)
|
||||
broken/ShutdownOnFailure.java:6: error: cannot find symbol
|
||||
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
|
||||
^
|
||||
symbol: class ShutdownOnFailure
|
||||
location: interface StructuredTaskScope
|
||||
1 error
|
||||
exit=1
|
||||
|
||||
$ javac broken/ShutdownOnFailure.java (28-beta+21-ea)
|
||||
broken/ShutdownOnFailure.java:6: error: cannot find symbol
|
||||
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
|
||||
^
|
||||
symbol: class ShutdownOnFailure
|
||||
location: interface StructuredTaskScope
|
||||
1 error
|
||||
exit=1
|
||||
|
||||
# the same sources on JDK 25 for ShutdownOnFailure
|
||||
$ javac --enable-preview --release 25 broken/ShutdownOnFailure.java (25.0.5+8-LTS)
|
||||
broken/ShutdownOnFailure.java:6: error: cannot find symbol
|
||||
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
|
||||
^
|
||||
symbol: class ShutdownOnFailure
|
||||
location: interface StructuredTaskScope
|
||||
1 error
|
||||
exit=1
|
||||
@@ -0,0 +1,59 @@
|
||||
# compile on 27 with preview, then run the class file on 27 and on 28
|
||||
$ java --enable-preview Server (27.0.1.0.2+1)
|
||||
Response[user=Alice, order=42]
|
||||
Runtime: 27.0.1.0.2+1
|
||||
$ java --enable-preview Server (28-beta+21-ea)
|
||||
Error: LinkageError occurred while loading main class Server
|
||||
java.lang.UnsupportedClassVersionError: Server (class file version 71.65535) was compiled with preview features that are unsupported. This version of the Java Runtime only recognizes preview features for class file version 72.65535
|
||||
$ java Server (27.0.1.0.2+1)
|
||||
Error: LinkageError occurred while loading main class Server
|
||||
java.lang.UnsupportedClassVersionError: Preview features are not enabled for Server (class file version 71.65535). Try running with '--enable-preview'
|
||||
|
||||
# the class file's minor version
|
||||
minor version: 65535
|
||||
major version: 71
|
||||
|
||||
# javac 28 asked for --release 27
|
||||
$ javac --release 27 src/Server.java (28-beta+21-ea)
|
||||
src/Server.java:2: error: StructuredTaskScope is a preview API and is disabled by default.
|
||||
import java.util.concurrent.StructuredTaskScope;
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:3: error: StructuredTaskScope is a preview API and is disabled by default.
|
||||
import java.util.concurrent.StructuredTaskScope.Subtask;
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:3: error: Subtask is a preview API and is disabled by default.
|
||||
import java.util.concurrent.StructuredTaskScope.Subtask;
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:22: error: StructuredTaskScope is a preview API and is disabled by default.
|
||||
try (var scope = StructuredTaskScope.open()) { // 1. open
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:23: error: Subtask is a preview API and is disabled by default.
|
||||
Subtask<String> user = scope.fork(this::findUser); // 2. fork
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
src/Server.java:24: error: Subtask is a preview API and is disabled by default.
|
||||
Subtask<Integer> order = scope.fork(this::fetchOrder); // fork
|
||||
^
|
||||
(use --enable-preview to enable preview APIs)
|
||||
6 errors
|
||||
|
||||
# javac 28 with --enable-preview --release 28 on the same file (nothing in it needs preview)
|
||||
$ javac --enable-preview --release 28 src/Server.java (28-beta+21-ea)
|
||||
Note: src/Server.java uses preview features of Java SE 28.
|
||||
Note: Recompile with -Xlint:preview for details.
|
||||
exit=0
|
||||
|
||||
# where that Note comes from: the first lines of -Xlint:preview
|
||||
$ javac --enable-preview --release 28 -Xlint:preview src/Server.java 2>&1 | head -3 (28-beta+21-ea)
|
||||
warning: [preview] class file for /@/java.base/java/lang/Record.sig uses preview features of Java SE 28.
|
||||
warning: [preview] class file for /@/java.base/java/time/Duration.sig uses preview features of Java SE 28.
|
||||
warning: [preview] class file for /@/java.base/java/lang/Integer.sig uses preview features of Java SE 28.
|
||||
|
||||
# recompile on 28 without any flag and run on 28
|
||||
$ javac src/Server.java && java Server (28-beta+21-ea)
|
||||
Response[user=Alice, order=42]
|
||||
Runtime: 28-beta+21-ea
|
||||
@@ -0,0 +1,9 @@
|
||||
$ javac src/Snippets.java && java Snippets (28-beta+21-ea)
|
||||
Response[user=Alice, order=42]
|
||||
Response[user=Alice, order=42]
|
||||
[1, 2]
|
||||
a
|
||||
Response[user=Alice, order=42]
|
||||
|
||||
$ javac src/QuickReference.java && java QuickReference (28-beta+21-ea)
|
||||
quick reference compiled and ran
|
||||
@@ -0,0 +1,20 @@
|
||||
$ java RandomTasks 5 (28-beta+21-ea)
|
||||
Duration: 487
|
||||
Duration: 92
|
||||
Duration: 474
|
||||
Duration: 424
|
||||
Duration: 506
|
||||
Result: 487
|
||||
Result: 92
|
||||
Result: 474
|
||||
Result: 424
|
||||
Result: 506
|
||||
|
||||
$ java RandomTasks 3 (28-beta+21-ea)
|
||||
Duration: 734
|
||||
Duration: 660
|
||||
Duration: 210
|
||||
Duration: 581
|
||||
Duration: 128
|
||||
ExecutionException: TooSlowException: Duration 734 greater than threshold 700
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
$ javac src/StuckClose.java && java StuckClose (28-beta+21-ea)
|
||||
subtask that responds to interrupts: caught fails at 50 ms; the try block took >= 1400 ms: false
|
||||
subtask that ignores interrupts : caught fails at 50 ms; the try block took >= 1400 ms: true
|
||||
@@ -0,0 +1,23 @@
|
||||
$ jcmd <pid> Thread.dump_to_file -format=json threads.json (28-beta+21-ea)
|
||||
<pid>:
|
||||
Created <tmp>/threads.json
|
||||
|
||||
# the scope "orders" and its child scope in threads.json (stack frames, timestamps and ids trimmed or masked)
|
||||
"container": "orders\/jdk.internal.misc.ThreadFlock$ThreadContainerImpl@<hash>",
|
||||
"parent": "<root>",
|
||||
"owner": <n>,
|
||||
"tid": <n>,
|
||||
"virtual": true,
|
||||
"state": "TIMED_WAITING",
|
||||
"ThreadDump.lambda$main$1(ThreadDump.java:12)",
|
||||
"tid": <n>,
|
||||
"virtual": true,
|
||||
"state": "WAITING",
|
||||
"ThreadDump.lambda$main$2(ThreadDump.java:16)",
|
||||
"container": "inventory\/jdk.internal.misc.ThreadFlock$ThreadContainerImpl@<hash>",
|
||||
"parent": "orders\/jdk.internal.misc.ThreadFlock$ThreadContainerImpl@<hash>",
|
||||
"owner": <n>,
|
||||
"tid": <n>,
|
||||
"virtual": true,
|
||||
"state": "TIMED_WAITING",
|
||||
"ThreadDump.lambda$main$4(ThreadDump.java:15)",
|
||||
Reference in New Issue
Block a user