0Pricing
Java Academy · Lektion

Future und Fehlerbehandlung

Verwenden Sie Future.get mit Zeitüberschreitungen, behandeln Sie ExecutionException und brechen Sie laufende Aufgaben ab.

Future und Fehlerbehandlung ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist ein Future?

Ein Future<V> repräsentiert das ausstehende Ergebnis einer asynchronen Berechnung. Es stellt Methoden bereit, um den Abschluss zu prüfen, auf das Ergebnis zu warten und Fehler zu behandeln.

import java.util.concurrent.*;

ExecutorService pool = Executors.newFixedThreadPool(2);
Future<Integer> future = pool.submit(() -> {
    Thread.sleep(1000);
    return 42;
});

System.out.println("Is done? " + future.isDone()); // false
Integer result = future.get(); // blocks
System.out.println("Result: " + result); // 42
pool.shutdown();

future.get() mit Timeout

Verwenden Sie stets bevorzugt die Variante mit Timeout, damit nicht unbegrenzt gewartet wird:

try {
    Integer result = future.get(5, TimeUnit.SECONDS);
    System.out.println(result);
} catch (TimeoutException e) {
    System.out.println("Timed out");
    future.cancel(true); // interrupt the task
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
} catch (ExecutionException e) {
    System.out.println("Task threw: " + e.getCause());
}

ExecutionException

Wenn die Aufgabe eine Ausnahme ausgelöst hat, verpackt future.get() sie in eine ExecutionException. Entpacken Sie sie mit getCause():

Future<String> failing = pool.submit(() -> {
    throw new IllegalArgumentException("bad input");
});

try {
    failing.get();
} catch (ExecutionException e) {
    Throwable cause = e.getCause();
    System.out.println(cause.getClass().getSimpleName()); // IllegalArgumentException
    System.out.println(cause.getMessage()); // bad input
}

Ein Future abbrechen

cancel(mayInterruptIfRunning) versucht, die Aufgabe abzubrechen. Bei Erfolg wird true zurückgegeben. Wenn mayInterruptIfRunning den Wert true hat, wird ein Interrupt an den laufenden Thread gesendet.

Future<String> f = pool.submit(() -> {
    try {
        Thread.sleep(10_000); // long task
        return "done";
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        return "interrupted";
    }
});

boolean cancelled = f.cancel(true); // send interrupt
System.out.println("Cancelled: " + cancelled); // true
System.out.println("Is cancelled: " + f.isCancelled()); // true

isCancelled vs. isDone

isDone() gibt true zurück, wenn die Aufgabe normal abgeschlossen, eine Ausnahme ausgelöst oder abgebrochen wurde. isCancelled() gibt nur dann true zurück, wenn die Aufgabe abgebrochen wurde.

// After cancel:
System.out.println(f.isDone());       // true
System.out.println(f.isCancelled()); // true

// After normal completion:
Future<Integer> done = pool.submit(() -> 5);
done.get(); // wait
System.out.println(done.isDone());       // true
System.out.println(done.isCancelled()); // false

CompletionService für zuerst verfügbare Ergebnisse

ExecutorCompletionService kapselt einen Pool und stellt eine take()-Methode bereit, mit der das nächste abgeschlossene Future abgerufen wird (in Abschlussreihenfolge, nicht in der Reihenfolge der Übergabe):

ExecutorCompletionService<Integer> cs =
    new ExecutorCompletionService<>(pool);

for (int i = 0; i < 5; i++) {
    final int delay = 5 - i; // submit fastest last
    cs.submit(() -> { Thread.sleep(delay * 100); return delay; });
}

for (int i = 0; i < 5; i++) {
    Future<Integer> f = cs.take(); // next completed
    System.out.println(f.get());
}

Mehrere Futures sicher verarbeiten

Wenn Sie Ergebnisse aus vielen Futures sammeln, durchlaufen Sie sie und behandeln Sie Ausnahmen für jedes Future einzeln:

List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    final int id = i;
    futures.add(pool.submit(() ->
        id % 2 == 0 ? "ok_" + id : (() -> { throw new RuntimeException("fail_"+id); }).get()
    ));
}

for (Future<String> f : futures) {
    try {
        System.out.println(f.get());
    } catch (ExecutionException e) {
        System.out.println("Error: " + e.getCause().getMessage());
    }
}

Future.get() nach dem Herunterfahren des Pools

Eine Übergabe nach shutdown() löst RejectedExecutionException aus. Futures, die VOR dem Herunterfahren übergeben wurden, können jedoch auch danach noch abgerufen werden:

ExecutorService pool2 = Executors.newFixedThreadPool(2);
Future<Integer> f = pool2.submit(() -> 99);
pool2.shutdown(); // no new tasks

// Still valid — task was submitted before shutdown:
System.out.println(f.get()); // 99

try {
    pool2.submit(() -> 0); // throws!
} catch (RejectedExecutionException e) {
    System.out.println("Pool shut down");
}

FutureTask: Manuelles Future

FutureTask<V> implementiert sowohl Runnable als auch Future<V> – nützlich, wenn Sie ein Future ohne ExecutorService benötigen:

FutureTask<String> task = new FutureTask<>(() -> "computed");
new Thread(task).start(); // run in any thread
System.out.println(task.get()); // computed

Wiederholungsmuster mit Future

Implementieren Sie eine einfache Logik für Wiederholungsversuche rund um future.get():

Future<String> future = pool.submit(() -> {
    if (Math.random() < 0.7) throw new RuntimeException("transient error");
    return "success";
});

for (int attempt = 0; attempt < 3; attempt++) {
    try {
        System.out.println(future.get());
        break;
    } catch (ExecutionException e) {
        System.out.println("Attempt " + (attempt+1) + " failed");
        if (attempt == 2) throw e;
        future = pool.submit(() -> "retry"); // resubmit
    }
}

Einschränkungen von Future

java.util.concurrent.Future hat einige Einschränkungen:

  • Keine Callbacks – Sie müssen mit get() blockieren
  • Transformationen können nicht verkettet werden
  • Mehrere Futures können nicht kombiniert werden

Verwenden Sie CompletableFuture (im nächsten Kurs) für eine reaktive, nicht blockierende Komposition.

Kurzer Test

Eine Aufgabe löst eine Ausnahme aus. Welche Ausnahme wird ausgelöst, wenn Sie future.get() aufrufen?

Zusammenfassung: Future und Fehlerbehandlung

Die wichtigsten Punkte:

  • future.get() blockiert; verwenden Sie stets die Variante mit Timeout
  • ExecutionException verpackt Ausnahmen aus Aufgaben; entpacken Sie sie mit getCause()
  • cancel(true) sendet einen Interrupt; isDone/isCancelled geben den Status an
  • ExecutorCompletionService.take() ruft Futures in Abschlussreihenfolge ab
  • FutureTask implementiert sowohl Runnable als auch Future

Häufig gestellte Fragen

Ist die Lektion „Future und Fehlerbehandlung“ kostenlos?

Ja — der vollständige Text von „Future und Fehlerbehandlung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Future und Fehlerbehandlung“?

Verwenden Sie Future.get mit Zeitüberschreitungen, behandeln Sie ExecutionException und brechen Sie laufende Aufgaben ab. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Future und Fehlerbehandlung“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. ExecutorService und Thread-Pool-Typen
  2. Aufgaben übermitteln: Runnable vs. Callable
  3. Future und Fehlerbehandlung
  4. ScheduledExecutorService für wiederkehrende Aufgaben
← Zurück zu Java Academy