Files
javademos/structured-concurrency-final/README.md
T
Claude c93a1fffbb 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
2026-10-26 02:01:31 +00:00

48 lines
3.5 KiB
Markdown

# structured-concurrency-final — Structured Concurrency, final in JDK 28 (JEP 543)
Companion code for the ankurm.com article **Structured Concurrency Is Final in JDK 28 (JEP 543): From Preview to Production**
(<https://ankurm.com/structured-concurrency-java/>). The explanation lives in the article, in collapsible sections; this folder holds the runnable
sources and the transcripts they produced.
```bash
JDK25=/path/to/jdk-25 JDK26=/path/to/jdk-26 JDK27=/path/to/jdk-27 JDK28=/path/to/jdk-28 ./run.sh # regenerates output/*.txt
```
## What was tested against
| Thing | Build | Note |
|---|---|---|
| JDK 28 | Temurin `28-beta+21-ea` (28-ea+21, build of 2026-10-22) | **early access**; JEP 543 status "Integrated", GA proposed 2027-03-09. No flags needed |
| JDK 27 | Temurin 27.0.1.0.2+1 | GA 2026-09-15. Seventh preview (JEP 533): needs `--enable-preview` |
| JDK 26 | Temurin 26.0.2.1+1 | sixth preview (JEP 525), for the old-API compile results |
| JDK 25 | Temurin 25.0.5+8 | fifth preview (JEP 505), for the API diffs |
`javap` prints identical `StructuredTaskScope` signatures on 27 and on 28-ea+21 (`output/09-api-diff.txt`). Nothing here was run on a GA JDK 28, because none exists yet.
## Layout
- `src/` — runnable demos, no flags on JDK 28: `Server` (the canonical program), `Unstructured` and `FailFast` (the thread leak and its fix),
`Joiners` (the built-in joiners), `Failures` (structure violations and failure handling), `Timeouts`, `CollectingJoiner` (a custom joiner),
`RandomTasks` (seeded), `StuckClose` (a subtask that ignores interrupts), `ThreadDump` (JSON thread dump with the scope hierarchy),
`ScopedValues`, `Snippets` and `QuickReference` (the short fragments quoted in the article).
- `broken/` — six sources that compile on JDK 26 and fail on 28: `MissingCatch`, `OldFailedException`, `OldTimeoutException`, `AwaitAll`, `OldJoiner`, `ShutdownOnFailure`.
- `output/` — one transcript per script step; `run.sh` regenerates all of them.
| Transcript | What it shows |
|---|---|
| `01-server.txt` | the canonical program on 28 (no flags), on 27 (`--enable-preview`), and the 27 compile errors without the flag |
| `02-unstructured-vs-structured.txt` | `ExecutorService` leaks the sibling; `StructuredTaskScope` interrupts it |
| `03-joiners.txt` | `allSuccessfulOrThrow`, `anySuccessfulOrThrow`, `awaitAllSuccessfulOrThrow`, `allUntil`, the `Function` overloads |
| `04-failures.txt` | `get()` before `join()`, no `join()`, non-owner `fork`, out-of-order close, join twice, cause pattern matching |
| `05-timeouts-and-custom-joiner.txt` | scope timeouts, a partial-result `timeout()`, thread factory, a custom joiner |
| `06-thread-dump.txt`, `15-jcmd-thread-dump.txt` | the scope as a container in a JSON thread dump (in-process and via `jcmd`) |
| `07-scoped-values.txt` | subtasks inherit a `ScopedValue` binding, a plain thread does not |
| `08-api-28.txt`, `09-api-diff.txt` | `javap` of the API on 28, and the diffs 25 to 26 to 27 to 28 |
| `10-broken-old-api.txt` | the compiler's messages for 25/26-era code on 28 |
| `11-preview-traps.txt` | a class compiled with preview on 27 does not load on 28; `--release 27` on a 28 compiler |
| `12-snippets.txt` | the short fragments in the article compile and run |
| `13-random-tasks.txt`, `14-stuck-close.txt` | seeded fan-out with one slow task; a subtask that ignores interrupts |
Everything is byte-stable between runs (timings are reduced to booleans). The JEP statements (what changed in each preview) come from the JEP texts on openjdk.org;
only the 25 to 28 API differences were checked against binaries.