☕🧵 STRUCTURED CONCURRENCY LOOMS: Java's next CONCURRENCY REVOLUTION
☕🧵 STRUCTURED CONCURRENCY LOOMS: Java's next CONCURRENCY REVOLUTION
Virtual Threads made concurrency cheaper. Now make it manageable.
🔸 TL;DR
Virtual Threads changed HOW Java executes concurrent tasks.
Structured Concurrency changes HOW Java manages them.
At Devoxx Belgium 2026, Alan Bateman and Viktor Klang, from Oracle's Java Platform team, explored Project Loom's next major feature.
The objective? Treat related concurrent tasks as one unit of work, with coordinated cancellation, error handling, and observability.

Let's explore the API with 4️⃣ Java snippets. 🚀
🔸 1️⃣ THE PROBLEM: EXECUTOR SERVICE
Imagine fetching a customer and an order from independent services.
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { var customer = executor.submit( () -> fetchCustomer()); var order = executor.submit( () -> fetchOrder()); return new OrderSummary( customer.get(), order.get()); }
Both tasks run concurrently, but what happens if one fails?
▪️ Future.get() may wait for another task unnecessarily.
▪️ Cancellation must be coordinated manually.
▪️ Debugging loses the parent-child task relationship.
▪️ Cleanup becomes harder to reason about.
Virtual Threads alone don't solve task lifecycle management.
🔸 2️⃣ THE SOLUTION: STRUCTURED TASK SCOPE
Now rewrite the same operation with StructuredTaskScope.
try (var scope = StructuredTaskScope.open()) { var customer = scope.fork( () -> fetchCustomer()); var order = scope.fork( () -> fetchOrder()); scope.join(); return new OrderSummary( customer.get(), order.get()); }
Much clearer!
▪️ fork() starts independent subtasks, using Virtual Threads by default.
▪️ join() coordinates their completion.
▪️ A failed subtask triggers cancellation of its siblings.
▪️ close() ensures child threads finish before the scope is exited.
The execution structure now reflects the logical structure of the code.
⚠️ Cancellation uses thread interruption. Subtasks must cooperate; otherwise, closing the scope can remain blocked.
🔸 3️⃣ JOINERS: DEFINE YOUR SUCCESS STRATEGY
Not every concurrent operation needs all results.
Suppose you're querying two independent replicas and want the first successful response.
try (var scope = StructuredTaskScope.open( Joiner.<String>anySuccessfulOrThrow())) { scope.fork(() -> queryReplicaA()); scope.fork(() -> queryReplicaB()); return scope.join(); }
The first successful result wins! 🏆
The other subtask is cancelled.
Available strategies include:
▪️ awaitAllSuccessfulOrThrow(): all subtasks must succeed.
▪️ allSuccessfulOrThrow(): collect every successful result, or fail.
▪️ anySuccessfulOrThrow(): return any successful result.
▪️ allUntil(predicate): stop when a condition is satisfied.
You can even define custom Joiners for more advanced coordination policies.
🔸 4️⃣ TIMEOUTS: BOUND YOUR CONCURRENT WORK
What if a service doesn't respond?
try (var scope = StructuredTaskScope.open( Joiner.<String>anySuccessfulOrThrow(), config -> config.withTimeout( Duration.ofSeconds(3)))) { scope.fork(() -> queryReplicaA()); scope.fork(() -> queryReplicaB()); return scope.join(); }
After 3 seconds, if no task has succeeded, the scope is cancelled.
The timeout starts when the scope is opened, not when join() is called.
And closing the scope still waits for subtasks to terminate.
🔸 OBSERVABILITY: A TREE INSTEAD OF A THREAD LIST 🌳
Traditional concurrency makes thread relationships difficult to reconstruct.
With Structured Concurrency, subtasks form a parent-child tree.
OrderSummary ├── fetchCustomer │ ├── fetchProfile │ ├── fetchPreferences │ └── fetchAccountStatus └── fetchOrder
Structured thread dumps preserve these relationships.
This makes diagnosing failures, hangs, and cancellation significantly easier.
The speakers also demonstrated how JSON thread dumps can be processed to reconstruct the task tree.
🔸 WHAT'S NEXT FOR PROJECT LOOM?
After several preview iterations, Structured Concurrency was proposed to become permanent in JDK 28, as explained during the October 12, 2026 session.
But Bateman emphasized that StructuredTaskScope is an on-ramp, not the definitive concurrency API.
Future investigations include:
▪️ Lower-level structured concurrency primitives
▪️ Dependent tasks and workflow orchestration
▪️ Producer-consumer patterns and channels
▪️ Structured memory lifetimes with the Foreign Function & Memory API
The ambition goes beyond simplifying Futures.
🔸 TAKEAWAYS
▪️ Virtual Threads solve scalability, not coordination.
▪️ Structured Concurrency gives related tasks a common lifecycle.
▪️ Joiners make concurrency policies explicit.
▪️ Cancellation and exceptions become easier to manage.
▪️ Structured thread dumps improve debugging.
▪️ Project Loom is moving from lightweight threads to structured execution.
The biggest concurrency improvement may not be running more threads. It may be knowing exactly when they should stop. ☕
Code examples use the Java 27 preview API and require preview features to be enabled.
#Java #ProjectLoom #StructuredConcurrency #VirtualThreads #JDK28 #Java27 #Concurrency #SoftwareArchitecture #Devoxx #DevoxxBE #JavaDevelopment
Go further with Java certification:
Java👇
Spring👇
SpringBook👇
JavaFullstackBook👇
