Die CompletableFuture-Klasse wurde mit Java 8 eingeführt und hat die Art und Weise, wie Entwickler asynchrone Programmierung in Java angehen, grundlegend verändert. Diese Klasse bietet eine mächtige und flexible API für die asynchrone Programmierung und ermöglicht es Entwicklern, komplexe Aufgaben effizient zu parallelisieren. In diesem Artikel werden wir die CompletableFuture-Klasse in Java im Detail untersuchen, ihre Funktionalitäten, Anwendungsfälle und bewährte Praktiken kennenlernen.

1. Einführung in CompletableFuture

Die CompletableFuture-Klasse gehört zum java.util.concurrent-Paket und basiert auf dem Future-Pattern. Sie erweitert das traditionelle Future-Konzept, indem sie Funktionalitäten für asynchrone Operationen und Verknüpfung von Futures bereitstellt. Ein CompletableFuture repräsentiert eine potenziell abgeschlossene Berechnung und ermöglicht es, Callbacks zu registrieren, die automatisch aufgerufen werden, wenn die Berechnung abgeschlossen ist.

2. Grundlegende Verwendung von CompletableFuture

2.1. Erstellen von CompletableFuture

Ein CompletableFuture kann auf verschiedene Arten erstellt werden. Eine häufige Methode ist CompletableFuture.supplyAsync, die eine Berechnung asynchron ausführt:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, CompletableFuture");Code-Sprache: JavaScript (javascript)

2.2. Kombination von CompletableFuture

CompletableFuture ermöglicht die Verknüpfung von mehreren Futures, um komplexe Abläufe zu erstellen. Zum Beispiel können wir zwei CompletableFuture-Objekte kombinieren und eine Aktion ausführen, wenn beide abgeschlossen sind:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "CompletableFuture");

CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2);Code-Sprache: JavaScript (javascript)

3. Verkettung von CompletableFuture

Eine der leistungsstarken Funktionen von CompletableFuture ist die Möglichkeit, Aktionen zu verketten, die sequentiell oder parallel ausgeführt werden können. Dies wird durch Methoden wie thenApply, thenAccept, und thenCompose ermöglicht.

CompletableFuture<String> originalFuture = CompletableFuture.supplyAsync(() -> "Hello");

CompletableFuture<String> chainedFuture = originalFuture
    .thenApply(result -> result + ", World")
    .thenApply(String::toUpperCase)
    .thenAccept(System.out::println);Code-Sprache: JavaScript (javascript)

4. Ausnahmebehandlung mit CompletableFuture

Die CompletableFuture-Klasse ermöglicht auch eine effektive Behandlung von Ausnahmen. Sie können die exceptionally-Methode verwenden, um einen Fehler abzufangen und einen Standardwert oder ein Ersatzergebnis bereitzustellen:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // Simulieren einer Ausnahme
    throw new RuntimeException("Oops! Something went wrong");
});

CompletableFuture<String> result = future.exceptionally(ex -> "Default Value");Code-Sprache: JavaScript (javascript)

5. Parallele Ausführung mit CompletableFuture

Ein entscheidender Vorteil von CompletableFuture besteht darin, dass es einfach ist, Aufgaben parallel auszuführen. Durch die Verwendung von Methoden wie thenCombine und thenAcceptBoth können Sie Ergebnisse von mehreren Futures kombinieren:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "CompletableFuture");

CompletableFuture<Void> combinedFuture = future1.thenAcceptBoth(future2, (result1, result2) -> {
    System.out.println(result1 + " " + result2);
});Code-Sprache: JavaScript (javascript)

6. Timeout und Abbruch von CompletableFuture

Mit CompletableFuture können Sie auch einen Timeout für eine Operation festlegen und eine alternative Aktion ausführen, wenn die Operation nicht innerhalb eines bestimmten Zeitrahmens abgeschlossen wird:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // Simuliere eine lang andauernde Operation
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "Hello";
});

CompletableFuture<String> result = future.orTimeout(3, TimeUnit.SECONDS)
    .exceptionally(ex -> "Operation timed out");Code-Sprache: JavaScript (javascript)

7. CompletableFuture und CompletableFuture.allOf

Wenn Sie eine Gruppe von CompletableFuture-Objekten haben und warten möchten, bis alle abgeschlossen sind, können Sie die CompletableFuture.allOf-Methode verwenden:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "CompletableFuture");
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "Java");

CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2, future3);

// Warten, bis alle abgeschlossen sind
allOfFuture.join();Code-Sprache: JavaScript (javascript)

8. Fazit

Die CompletableFuture-Klasse in Java bietet eine leistungsstarke Möglichkeit, asynchrone Programmierung durchzuführen. Von der einfachen Parallelisierung von Aufgaben bis hin zur komplexen Verkettung von Aktionen und der effektiven Behandlung von Ausnahmen bietet diese Klasse eine Fülle von Funktionen. Es ist wichtig, die API gründlich zu verstehen und bewährte Praktiken zu beachten, um sicherzustellen, dass Sie das volle Potenzial von CompletableFuture nutzen und robusten, wartbaren Code schreiben.