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()); // trueisCancelled 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()); // falseCompletionService 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()); // computedWiederholungsmuster 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
- ExecutorService und Thread-Pool-Typen
- Aufgaben übermitteln: Runnable vs. Callable
- Future und Fehlerbehandlung
- ScheduledExecutorService für wiederkehrende Aufgaben