Completablefuture
Es fehlt nur noch ein letzter Schritt! In diesem Kapitel betrachten wir die Hauptklasse für Asynchronität, CompletableFuture.
Verwendung einer Alltagsanalogie. Über eine App wird ein Taxi gerufen (Aufgabenerstellung). Während der Wartezeit kann die App Aktualisierungen zum Standort des Fahrzeugs oder zur voraussichtlichen Ankunftszeit bereitstellen (Ergebnisverarbeitung). Bei Problemen wie Verzögerungen oder Stornierungen informiert die App und schlägt Alternativen vor (Fehlerbehandlung).
Hauptmethoden
Die erste Frage könnte sein, wie eine Aufgabe mit CompletableFuture gestartet werden kann. Hierfür steht die Methode supplyAsync() zur Verfügung, die eine Aufgabe asynchron mit Rückgabewert ausführt.
Main.java
12345678910// Creating an asynchronous task CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Result"; // Result }); // Processing the result after the task completes future.thenAccept(result -> { // Print the result to the console System.out.println("Result received: " + result); // Result received: });
Es gibt auch die Methode thenAccept(), die den von CompletableFuture zurückgegebenen Wert im asynchronen Code verarbeitet. Sie gibt keinen Wert zurück; sie ist nützlich, wenn eine Antwort angenommen und auf bestimmte Weise verarbeitet werden soll.
Im Beispiel wird die Aufgabe asynchron ausgeführt, und future.thenAccept() erhält die Antwort von der Lambda-Funktion, die anschließend zur Ausgabe auf der Konsole verwendet werden kann.
Es gibt eine ähnliche Methode, thenApply(), die wie thenAccept() funktioniert, aber das Ergebnis der asynchronen Aufgabe erhält und ein neues Ergebnis zurückgibt.
Main.java
12345678910// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Transforming the result to uppercase CompletableFuture<String> transformedFuture = future.thenApply(result -> result.toUpperCase()); // Printing the transformed result to the console transformedFuture.thenAccept(result -> { System.out.println("Transformed result: " + result); // Transformed result: });
Was ist, wenn wir das Ergebnis der asynchronen Aufgabe nicht benötigen, sondern lediglich benachrichtigt werden möchten, wenn sie abgeschlossen ist?
Dafür kann thenRun() verwendet werden, das nach dem Abschluss der asynchronen Aufgabe ausgeführt wird.
Main.java
12345678// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Running a task when the previous task completes future.thenRun(() -> { // Print message to the console indicating that the task is complete System.out.println("Task completed!"); // Task completed! });
Das Ergebnis einer asynchronen Aufgabe kann auch abgerufen werden, indem der aktuelle Thread blockiert wird, bis die Aufgabe abgeschlossen ist. Zu diesem Zweck wird die Methode get() verwendet.
Main.java
1234567CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
Es gibt auch eine Methode join(), die ebenfalls den aktuellen Thread pausiert und auf den Abschluss der asynchronen Aufgabe wartet. Der Unterschied zwischen join() und get() besteht jedoch darin, dass sie unterschiedliche Ausnahmen auslösen.
Main.java
12345// Create a `CompletableFuture` that asynchronously executes a task and returns the string "Hello World". CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); // The `join()` method blocks the current thread until the task is completed and returns the result "Hello World". String result = completableFuture.join();
Hier erfolgt keine Behandlung der Ausnahme, da die Methode join() eine unchecked CompletionException auslöst.
Aufgaben kombinieren und verketten
Mit CompletableFuture können Aufgaben mithilfe von thenCompose() kombiniert werden, um zwei abhängige Aufgaben zu verknüpfen.
Main.java
12345678910111213141516171819202122232425// Method to get book details from a remote service public CompletableFuture<String> getBookDetails() { return CompletableFuture.supplyAsync(() -> { // Request to a remote service to get book details return "Book Details"; // Placeholder for book details }); } // Method to get author details from a remote service public CompletableFuture<String> getAuthorDetails(String bookDetails) { return CompletableFuture.supplyAsync(() -> { // Request to another service to get author details return bookDetails + " Author"; // Placeholder for author details }); } // Combine two asynchronous tasks: get book details and then get author details CompletableFuture<String> result = getBookDetails() .thenCompose(book -> getAuthorDetails(book)); // Process the result and print the author details to the console result.thenAccept(author -> { // Print the author details to the console System.out.println("Author: " + author); // Author details });
Zuerst werden die Buchdaten asynchron mit der Methode getBookDetails() abgerufen. Anschließend wird das Ergebnis verwendet, um die nächste asynchrone Aufgabe auszuführen – das Abrufen der Autorendaten über die Methode getAuthorDetails(). Nachdem beide Aufgaben abgeschlossen sind, wird das Ergebnis (Autoreninformationen) auf der Konsole ausgegeben.
Wir können auch die Ergebnisse von zwei Aufgaben mit der Methode thenCombine() zusammenführen. Sie führt beide Aufgaben gleichzeitig aus und kombiniert deren Ergebnisse, sobald beide Aufgaben abgeschlossen sind.
Main.java
123456789101112// CompletableFuture for adding two numbers CompletableFuture<Double> firstNumberFuture = CompletableFuture.supplyAsync(() -> 50.0); CompletableFuture<Double> secondNumberFuture = CompletableFuture.supplyAsync(() -> 30.0); // Combine the two futures by adding their results CompletableFuture<Double> sumFuture = firstNumberFuture.thenCombine(secondNumberFuture, (first, second) -> first + second); // Print the result of the addition to the console sumFuture.thenAccept(sum -> { System.out.println("Sum: " + sum); // Sum: 80.0 });
Dieser Code ruft asynchron zwei Zahlen ab, summiert sie und gibt das Ergebnis auf der Konsole aus.
Wir können auch auf den Abschluss aller Aufgaben mit der Methode allOf() warten oder auf eine beliebige mit der Methode anyOf().
Main.java
1234567891011121314151617181920CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> { // Task 1 System.out.println("Task 1 completed"); }); CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> { // Task 2 System.out.println("Task 2 completed"); }); // Combine both futures and wait for both tasks to complete CompletableFuture<Void> combinedFuture1 = CompletableFuture.allOf(future1, future2); // Combine both futures and proceed as soon as any one task completes CompletableFuture<Object> combinedFuture2 = CompletableFuture.anyOf(future1, future2); // Print a message after all tasks are completed combinedFuture1.thenRun(() -> { System.out.println("All tasks completed"); });
Wie werden Fehler behandelt und was ist ein Timeout?
Kurzer Ausschnitt aus dem Video
handle(): Verarbeitung des Ergebnisses oder Behandlung von Ausnahmen, die durch dasCompletableFutureausgelöst wurden;exceptionally(): Behandlung von Ausnahmen, die während der Ausführung desCompletableFutureauftreten;completeOnTimeout(): Vervollständigung desCompletableFuturemit einem angegebenen Wert, falls ein Timeout vor Abschluss eintritt.
CompletableFuture erleichtert die Verwaltung asynchroner Aufgaben und die Verarbeitung ihrer Ergebnisse und ist somit ein leistungsfähiges Werkzeug für die Entwicklung moderner Anwendungen.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Awesome!
Completion rate improved to 3.33
Completablefuture
Swipe um das Menü anzuzeigen
Es fehlt nur noch ein letzter Schritt! In diesem Kapitel betrachten wir die Hauptklasse für Asynchronität, CompletableFuture.
Verwendung einer Alltagsanalogie. Über eine App wird ein Taxi gerufen (Aufgabenerstellung). Während der Wartezeit kann die App Aktualisierungen zum Standort des Fahrzeugs oder zur voraussichtlichen Ankunftszeit bereitstellen (Ergebnisverarbeitung). Bei Problemen wie Verzögerungen oder Stornierungen informiert die App und schlägt Alternativen vor (Fehlerbehandlung).
Hauptmethoden
Die erste Frage könnte sein, wie eine Aufgabe mit CompletableFuture gestartet werden kann. Hierfür steht die Methode supplyAsync() zur Verfügung, die eine Aufgabe asynchron mit Rückgabewert ausführt.
Main.java
12345678910// Creating an asynchronous task CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Result"; // Result }); // Processing the result after the task completes future.thenAccept(result -> { // Print the result to the console System.out.println("Result received: " + result); // Result received: });
Es gibt auch die Methode thenAccept(), die den von CompletableFuture zurückgegebenen Wert im asynchronen Code verarbeitet. Sie gibt keinen Wert zurück; sie ist nützlich, wenn eine Antwort angenommen und auf bestimmte Weise verarbeitet werden soll.
Im Beispiel wird die Aufgabe asynchron ausgeführt, und future.thenAccept() erhält die Antwort von der Lambda-Funktion, die anschließend zur Ausgabe auf der Konsole verwendet werden kann.
Es gibt eine ähnliche Methode, thenApply(), die wie thenAccept() funktioniert, aber das Ergebnis der asynchronen Aufgabe erhält und ein neues Ergebnis zurückgibt.
Main.java
12345678910// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Transforming the result to uppercase CompletableFuture<String> transformedFuture = future.thenApply(result -> result.toUpperCase()); // Printing the transformed result to the console transformedFuture.thenAccept(result -> { System.out.println("Transformed result: " + result); // Transformed result: });
Was ist, wenn wir das Ergebnis der asynchronen Aufgabe nicht benötigen, sondern lediglich benachrichtigt werden möchten, wenn sie abgeschlossen ist?
Dafür kann thenRun() verwendet werden, das nach dem Abschluss der asynchronen Aufgabe ausgeführt wird.
Main.java
12345678// Creating an asynchronous task that returns "Hello, World!" CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!"); // Running a task when the previous task completes future.thenRun(() -> { // Print message to the console indicating that the task is complete System.out.println("Task completed!"); // Task completed! });
Das Ergebnis einer asynchronen Aufgabe kann auch abgerufen werden, indem der aktuelle Thread blockiert wird, bis die Aufgabe abgeschlossen ist. Zu diesem Zweck wird die Methode get() verwendet.
Main.java
1234567CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); try { String result = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
Es gibt auch eine Methode join(), die ebenfalls den aktuellen Thread pausiert und auf den Abschluss der asynchronen Aufgabe wartet. Der Unterschied zwischen join() und get() besteht jedoch darin, dass sie unterschiedliche Ausnahmen auslösen.
Main.java
12345// Create a `CompletableFuture` that asynchronously executes a task and returns the string "Hello World". CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello World"); // The `join()` method blocks the current thread until the task is completed and returns the result "Hello World". String result = completableFuture.join();
Hier erfolgt keine Behandlung der Ausnahme, da die Methode join() eine unchecked CompletionException auslöst.
Aufgaben kombinieren und verketten
Mit CompletableFuture können Aufgaben mithilfe von thenCompose() kombiniert werden, um zwei abhängige Aufgaben zu verknüpfen.
Main.java
12345678910111213141516171819202122232425// Method to get book details from a remote service public CompletableFuture<String> getBookDetails() { return CompletableFuture.supplyAsync(() -> { // Request to a remote service to get book details return "Book Details"; // Placeholder for book details }); } // Method to get author details from a remote service public CompletableFuture<String> getAuthorDetails(String bookDetails) { return CompletableFuture.supplyAsync(() -> { // Request to another service to get author details return bookDetails + " Author"; // Placeholder for author details }); } // Combine two asynchronous tasks: get book details and then get author details CompletableFuture<String> result = getBookDetails() .thenCompose(book -> getAuthorDetails(book)); // Process the result and print the author details to the console result.thenAccept(author -> { // Print the author details to the console System.out.println("Author: " + author); // Author details });
Zuerst werden die Buchdaten asynchron mit der Methode getBookDetails() abgerufen. Anschließend wird das Ergebnis verwendet, um die nächste asynchrone Aufgabe auszuführen – das Abrufen der Autorendaten über die Methode getAuthorDetails(). Nachdem beide Aufgaben abgeschlossen sind, wird das Ergebnis (Autoreninformationen) auf der Konsole ausgegeben.
Wir können auch die Ergebnisse von zwei Aufgaben mit der Methode thenCombine() zusammenführen. Sie führt beide Aufgaben gleichzeitig aus und kombiniert deren Ergebnisse, sobald beide Aufgaben abgeschlossen sind.
Main.java
123456789101112// CompletableFuture for adding two numbers CompletableFuture<Double> firstNumberFuture = CompletableFuture.supplyAsync(() -> 50.0); CompletableFuture<Double> secondNumberFuture = CompletableFuture.supplyAsync(() -> 30.0); // Combine the two futures by adding their results CompletableFuture<Double> sumFuture = firstNumberFuture.thenCombine(secondNumberFuture, (first, second) -> first + second); // Print the result of the addition to the console sumFuture.thenAccept(sum -> { System.out.println("Sum: " + sum); // Sum: 80.0 });
Dieser Code ruft asynchron zwei Zahlen ab, summiert sie und gibt das Ergebnis auf der Konsole aus.
Wir können auch auf den Abschluss aller Aufgaben mit der Methode allOf() warten oder auf eine beliebige mit der Methode anyOf().
Main.java
1234567891011121314151617181920CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> { // Task 1 System.out.println("Task 1 completed"); }); CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> { // Task 2 System.out.println("Task 2 completed"); }); // Combine both futures and wait for both tasks to complete CompletableFuture<Void> combinedFuture1 = CompletableFuture.allOf(future1, future2); // Combine both futures and proceed as soon as any one task completes CompletableFuture<Object> combinedFuture2 = CompletableFuture.anyOf(future1, future2); // Print a message after all tasks are completed combinedFuture1.thenRun(() -> { System.out.println("All tasks completed"); });
Wie werden Fehler behandelt und was ist ein Timeout?
Kurzer Ausschnitt aus dem Video
handle(): Verarbeitung des Ergebnisses oder Behandlung von Ausnahmen, die durch dasCompletableFutureausgelöst wurden;exceptionally(): Behandlung von Ausnahmen, die während der Ausführung desCompletableFutureauftreten;completeOnTimeout(): Vervollständigung desCompletableFuturemit einem angegebenen Wert, falls ein Timeout vor Abschluss eintritt.
CompletableFuture erleichtert die Verwaltung asynchroner Aufgaben und die Verarbeitung ihrer Ergebnisse und ist somit ein leistungsfähiges Werkzeug für die Entwicklung moderner Anwendungen.
Danke für Ihr Feedback!