0Pricing
Java Academy · Lesson

StructuredTaskScope

Fork and join subtasks.

StructuredTaskScope is a free Java Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Meet StructuredTaskScope

StructuredTaskScope is the core API of structured concurrency. You open a scope, fork subtasks, join to wait for them, then read their results.

It is a preview feature, so compile and run with --enable-preview.

The Basic Lifecycle

Every use follows the same four-step rhythm:

  • Open the scope in a try-with-resources block
  • fork one or more subtasks, each returning a Subtask handle
  • join to wait for completion
  • Read each subtask's result via get()

Fork Returns a Handle

fork(Callable) immediately starts the subtask on a virtual thread and returns a Subtask. You must not call its get() until after join() returns.

A Complete Example

Here two subtasks run concurrently. Both must finish before we read results. This uses ShutdownOnFailure, a built-in policy.

import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            var name = scope.fork(() -> "Grace");
            var count = scope.fork(() -> 3);
            scope.join();
            scope.throwIfFailed();
            System.out.println(name.get() + " placed " + count.get() + " orders");
        }
    }
}

join Then Read

The ordering rule is strict: fork, then join, then get. Calling get() on a subtask before join() completes throws IllegalStateException.

This rule is what keeps the lifetime structured.

Subtask States

After join(), each Subtask reports a state():

  • SUCCESS with a result from get()
  • FAILED with the exception from exception()
  • UNAVAILABLE if it was never completed

Many Subtasks

You can fork as many subtasks as you like; each gets its own virtual thread. This is how you fan out a batch of independent calls.

import java.util.*;
import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            List<StructuredTaskScope.Subtask<Integer>> tasks = new ArrayList<>();
            for (int i = 1; i <= 5; i++) {
                final int n = i;
                tasks.add(scope.fork(() -> n * n));
            }
            scope.join();
            scope.throwIfFailed();
            int total = tasks.stream().mapToInt(StructuredTaskScope.Subtask::get).sum();
            System.out.println("Sum of squares 1..5 = " + total);
        }
    }
}

The Scope Owns the Threads

The scope is an AutoCloseable. When the try block ends, close() ensures every subtask thread has terminated. No leaks are possible.

This is why you always use it inside try-with-resources.

Built-in Policies

The JDK ships two ready-made shutdown policies:

  • ShutdownOnFailure: cancel the rest if any subtask fails
  • ShutdownOnSuccess: cancel the rest once one succeeds

You can also subclass StructuredTaskScope for custom logic.

Same Thread Joins

Only the thread that opened the scope may fork into it and call join. Subtasks are confined to their owning scope, which keeps the tree well-formed.

Compile and Run Flags

Because the API is preview, build with:

  • javac --release 21 --enable-preview Main.java
  • java --enable-preview Main

Without the flag you get a compilation or runtime error.

Quick Check

Recall the mandatory call order.

Recap

You learned the StructuredTaskScope API:

  • Open in try-with-resources, fork, join, then get
  • Each subtask runs on its own virtual thread
  • The scope guarantees all subtasks terminate before closing
  • Requires --enable-preview

Next: the shutdown-on-failure and shutdown-on-success policies in depth.

Frequently asked questions

Is the “StructuredTaskScope” lesson free?

Yes — the full text of “StructuredTaskScope” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.

What will I learn in “StructuredTaskScope”?

Fork and join subtasks. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Java Academy?

No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “StructuredTaskScope” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Java Academy lesson?

Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The Structured Concurrency Model
  2. StructuredTaskScope
  3. Shutdown on Failure and Success
  4. Error Handling and Cancellation
← Back to Java Academy