Production-minded Java 21 concurrency with virtual threads, bounded downstream resources, request coalescing, deadlines, cooperative cancellation, and deterministic tests. The examples start from failure modes seen in I/O-heavy services instead of treating concurrency as a collection of syntax demonstrations.
| Problem | Implementation | Behavioral proof |
|---|---|---|
| Duplicate concurrent requests repeat expensive work | SingleFlight<K,V> |
same-key and cancellation tests |
| Virtual threads overwhelm a scarce dependency | ConcurrencyLimiter |
capacity and interruption tests |
| One failed fan-out task leaves sibling work running | FailFastTaskGroup |
failure, deadline, and cancellation tests |
| Individual primitives look convincing but fail in composition | ProductAggregationService |
workflow tests |
The decision guide starts from operational constraints. The failure-mode catalog shows the tempting mistakes each component avoids.
Twelve callers request four products. Each product snapshot needs catalog, inventory, and delivery data from blocking downstream systems.
flowchart LR
Requests[12 product requests] --> Flight[Single-flight by product ID]
Flight -->|4 unique executions| Fanout[Fail-fast task group]
Fanout --> Catalog[Catalog limiter]
Fanout --> Inventory[Inventory limiter]
Fanout --> Delivery[Delivery limiter]
Catalog --> Snapshot[Immutable product snapshot]
Inventory --> Snapshot
Delivery --> Snapshot
Virtual threads make blocking calls inexpensive to represent. Separate fair limiters protect each backend because cheap threads do not create extra database connections, sockets, or downstream capacity.
Requirements: a full JDK 21 or newer.
./mvnw verify
java -jar product-aggregation-example/target/product-aggregation-example-0.1.0.jarExpected output:
requests=12 uniqueProducts=4 snapshots=12
singleFlight executions=4 joined=8
downstreamCalls catalog=4 inventory=4 delivery=4
peakConcurrency catalog=2 inventory=2 delivery=2
virtualThreadsOnly=true
| Component | Guarantee | Deliberate boundary |
|---|---|---|
| Single-flight | At most one operation per overlapping key within one JVM | It is not a cache or a distributed lock |
| Waiter future | One caller may cancel its own wait without cancelling shared work | The public API does not expose root-operation cancellation |
| Concurrency limiter | Active admitted operations never exceed the configured limit | Fair admission does not promise wall-clock completion order |
| Fail-fast task group | First observed failure or deadline requests interruption of unfinished siblings | Java cancellation is cooperative; code that ignores interruption may continue |
| Metrics snapshots | Counters are thread-safe and cheap to observe | A multi-counter snapshot is observational, not a transactional database record |
Executor ownership is external and explicit. The example closes its virtual-thread executor with try-with-resources. None of the core components silently creates a global pool.
java-concurrency-lab/
├── concurrency-core/ framework-free reusable components
├── product-aggregation-example/ executable fan-out/fan-in workflow
├── docs/ architecture, decisions, and failure modes
└── .github/workflows/ Java 21 and Java 25 verification
See architecture for ownership, thread-safety boundaries, and the failure path.
The Maven reactor runs 22 focused tests, compiler linting, dependency-convergence checks, and formatting verification. Tests coordinate races with latches and barriers; arbitrary sleeps are not used as correctness assertions. CI runs the same source and executable example on Java 21 and Java 25.
./mvnw spotless:apply
./mvnw clean verify- Virtual threads do not make CPU-bound work faster.
- Single-flight does not provide caching, idempotency, or cross-process coordination.
- A semaphore is not a distributed rate limiter.
Future.cancel(true)requests interruption; it cannot force uncooperative code to stop.- The example is not a benchmark. Throughput claims belong in the future
java-performance-lab. - Preview APIs are intentionally absent from the stable Java 21 source set.
- Java Patterns Playbook covers design selection and trade-offs without concurrency machinery.
- PDF Batch Studio applies bounded workers, cancellation, and asynchronous job state in a complete Spring Boot and JavaFX product.
Copyright 2026 Wasiliy Strecker. Licensed under the Apache License 2.0.