Czym jest CompletableFuture?
sobes.tech AI
Odpowiedź od AI
CompletableFuture w Java 8+ reprezentuje rozszerzenie modelu Future, dodając możliwości programowania asynchronicznego i kompozycji zadań.
Implementuje interfejsy CompletionStage i Future. CompletionStage definiuje kontrakt dla asynchronicznego wykonywania i kompozycji kroków obliczeniowych.
Kluczowe cechy:
- Operacje nieblokujące: Pozwala wykonywać zadania asynchronicznie, nie blokując głównego wątku.
- Kompozycja: Zapewnia bogate API do łączenia i łączenia wyników wielu operacji asynchronicznych.
- Obsługa wyjątków: Wbudowane mechanizmy obsługi błędów w strumieniach asynchronicznych.
- Tworzenie: Można tworzyć
CompletableFuturezakończone, nie zakończone lub z błędem. - Zależności: Pozwala tworzyć łańcuchy zależnych zadań, gdzie wykonanie jednego zależy od zakończenia drugiego.
- Wykonanie równoległe: Metody takie jak
allOfianyOfdo równoległego wykonywania wielu zadań.
Przykłady użycia:
-
Tworzenie i zakończenie:
// Tworzenie zakończonego CompletableFuture CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("Cześć"); // Tworzenie nieukończonego CompletableFuture i jego późniejsze zakończenie CompletableFuture<String> future = new CompletableFuture<>(); // ... wykonywanie pracy asynchronicznej ... future.complete("Gotowe"); // Lub w przypadku błędu // future.completeExceptionally(new RuntimeException("Błąd")); -
Wykonywanie zadania asynchronicznego:
CompletableFuture<String> asyncFuture = CompletableFuture.supplyAsync(() -> { // Praca asynchroniczna (np. czytanie z pliku, zapytanie sieciowe) try { Thread.sleep(1000); } catch (InterruptedException e) { throw new IllegalStateException(e); } return "Wynik asynchroniczny"; }); -
Kompozycja z
thenApply:CompletableFuture<Integer> result = CompletableFuture.supplyAsync(() -> 10) .thenApply(x -> x * 2); // Wynik poprzedniego kroku jest przekazywany do funkcji -
Kompozycja z
thenCombine:CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10); CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20); CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (res1, res2) -> res1 + res2); // Połączenie wyników dwóch CompletableFuture -
Obsługa zakończenia z
thenAccept:CompletableFuture.supplyAsync(() -> "Wynik końcowy") .thenAccept(result -> System.out.println("Zadanie zakończone z wynikiem: " + result)); // Wykonanie akcji po zakończeniu bez zwracania wartości -
Obsługa wyjątków z
exceptionally:CompletableFuture<String> futureWithException = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Coś poszło nie tak"); }).exceptionally(ex -> { System.err.println("Wystąpił błąd: " + ex.getMessage()); return "Wartość domyślna"; // Zwraca wartość domyślną w przypadku błędu });
CompletableFuture znacznie upraszcza pisanie kodu asynchronicznego i nieblokującego w Javie, czyniąc go bardziej czytelnym i łatwiejszym w utrzymaniu w porównaniu z tradycyjnymi callbackami lub blokującymi wywołaniami Future.get().