What is structured concurrency (StructuredTaskScope) and… — Cracked Java
// Concurrency & Multithreading · Virtual Threads & Structured Concurrency (Loom)
SeniorTheory

What is structured concurrency (StructuredTaskScope) and what does it improve?

Structured concurrency (StructuredTaskScope, JEP 453) treats a group of concurrent subtasks as a single unit of work with a defined lifetime: tasks forked in a scope must all complete before the scope exits, and errors and cancellation propagate as a unit. It brings the discipline of structured programming — clear entry and exit — to concurrency.

The problem it fixes

With a raw ExecutorService you can submit subtasks, then forget to handle one's failure, leak a thread when the parent returns early, or keep work running after the result is no longer needed. There is no enforced parent/child relationship, so cancellation and error handling are ad hoc and easy to get wrong. Structured concurrency makes that relationship explicit and scoped.

How it works

You open a scope in a try-with-resources block, fork() subtasks (each runs in its own virtual thread), then join() to wait for the group. Two ready-made policies:

  • ShutdownOnFailure — like an "all must succeed": if any subtask throws, the others are cancelled and join surfaces the failure. Use for fan-out where you need every result.
  • ShutdownOnSuccess — like a race: the first successful result cancels the rest. Use for redundant calls where any answer wins.
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
    Subtask<User>  user  = scope.fork(() -> userService.fetch(id));
    Subtask<Order> order = scope.fork(() -> orderService.fetch(id));

    scope.join();                 // wait for both
    scope.throwIfFailed();        // propagate first failure, cancel siblings

    return new Profile(user.get(), order.get());
}   // scope closes: guaranteed no subtask is still running

Why it pairs with virtual threads

Each fork spins up a virtual thread, so forking dozens of subtasks per request is cheap. Cancellation is cooperative via interruption: when the scope shuts down, it interrupts the unfinished subtasks, which unmount and unwind. The result is fan-out/fan-in code that reads top-to-bottom yet handles partial failure and timeouts correctly.

Mark your status