0Pricing
Java Academy · Lesson

Shutdown on Failure and Success

Coordinate task outcomes.

Shutdown on Failure and Success is a free Java Academy lesson on CoddyKit — lesson 3 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.

Two Common Patterns

Most concurrent fan-out falls into two shapes:

  • All must succeed: if any fails, abandon the rest. Use ShutdownOnFailure.
  • First wins: as soon as one succeeds, cancel the rest. Use ShutdownOnSuccess.

The JDK provides both out of the box.

ShutdownOnFailure Idea

ShutdownOnFailure is for tasks that all need to succeed, such as gathering a user profile and their orders together.

If one subtask throws, the scope cancels the others so you do not waste effort.

ShutdownOnFailure Example

After join() you call throwIfFailed(), which rethrows the first failure (if any) wrapped in an ExecutionException.

import java.util.concurrent.StructuredTaskScope;

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

    static String fetch(String what) {
        return what + "-ok";
    }
}

What throwIfFailed Does

throwIfFailed() inspects the subtasks. If all succeeded it does nothing. If any failed it throws, wrapping the original exception.

You can also pass a function to map the cause into a custom exception type.

ShutdownOnSuccess Idea

ShutdownOnSuccess is for redundancy or racing: query several mirrors and take whichever answers first.

The moment one subtask succeeds, the scope cancels the rest and stores the winning result.

ShutdownOnSuccess Example

You retrieve the winning value with result(). It throws if no subtask ever succeeded.

import java.util.concurrent.StructuredTaskScope;

public class Main {
    public static void main(String[] args) throws Exception {
        try (var scope = new StructuredTaskScope.ShutdownOnSuccess<String>()) {
            scope.fork(() -> queryMirror("eu"));
            scope.fork(() -> queryMirror("us"));
            scope.join();
            System.out.println("Fastest answer: " + scope.result());
        }
    }

    static String queryMirror(String region) {
        return region + "-data";
    }
}

result vs get

Note the difference:

  • ShutdownOnFailure: read each subtask with its own get()
  • ShutdownOnSuccess: read the single winner with the scope's result()

Cancellation Is Cooperative

When a scope shuts down, it interrupts the remaining subtask threads. Well-behaved tasks check interruption and stop promptly.

Blocking calls in the standard library generally respond to interruption automatically.

join with Timeout

Both policies support a deadline. Calling joinUntil(Instant) waits only until a point in time, then throws TimeoutException and shuts the scope down.

Choosing the Policy

Ask yourself one question: do I need all results, or just the first one?

  • All results, fail fast on error: ShutdownOnFailure
  • Any one result, fastest wins: ShutdownOnSuccess

For anything else, subclass StructuredTaskScope.

Custom Policies

You can extend StructuredTaskScope and override handleComplete(Subtask) to implement bespoke rules, like collecting the first N successes or shutting down after a quota of failures.

Quick Check

Match the scenario to the policy.

Recap

You learned the two built-in shutdown policies:

  • ShutdownOnFailure + throwIfFailed + per-subtask get for all-must-succeed
  • ShutdownOnSuccess + result for first-wins
  • Shutdown interrupts remaining subtasks cooperatively
  • joinUntil adds deadlines; subclassing adds custom rules

Next: error handling and cancellation in detail.

Frequently asked questions

Is the “Shutdown on Failure and Success” lesson free?

Yes — the full text of “Shutdown on Failure and Success” 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 “Shutdown on Failure and Success”?

Coordinate task outcomes. 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 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Shutdown on Failure and Success” 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