Middle
Opowiedz o koncepcji klasy CompletableFuture.
sobes.tech AI
Odpowiedź od AI
CompletableFuture to klasa w Java 8+ implementująca interfejsy Future i CompletionStage. Reprezentuje asynchroniczne obliczenie, które może zostać zakończone (lub zgłosić błąd) w pewnym momencie w przyszłości, i na którym można wykonywać kolejne działania deklaratywnie, bez blokowania głównego wątku.
Główne możliwości:
- Asynchronicjne wykonanie: Pozwala uruchamiać zadania w osobnym wątku (lub puli wątków).
- Kompozycja: Można łączyć wiele
CompletableFuture, tworząc łańcuchy zależnych działań. - Obsługa wyjątków: Udostępnia metody do obsługi błędów w asynchronicznych obliczeniach.
- Operacje nieblokujące: Wynik lub wyjątek są obsługiwane, gdy future się kończy, bez jawnego oczekiwania (
get()).
Kluczowe metody:
- Tworzenie:
supplyAsync(Supplier<T> supplier): Uruchamia dostawcę asynchronicznie i zwracaCompletableFuturez jego wynikiem.runAsync(Runnable runnable): UruchamiaRunnableasynchronicznie i zwracaCompletableFuture<Void>.completedFuture(T value): Tworzy już zakończonyCompletableFuturez podaną wartością.
- Przekształcanie:
thenApply(Function<T, U> fn): Zastosowuje funkcję do wyniku, gdy future się kończy.thenAccept(Consumer<T> action): Wykonuje akcję na wyniku, gdy future się kończy.thenRun(Runnable action): Wykonuje akcję, gdy future się kończy, ignorując wynik.thenCompose(Function<T, CompletionStage<U>> fn): Pozwala tworzyć łańcuchy, gdzie wynik jednego future jest używany do tworzenia kolejnego.
- Kombinacja:
thenCombine(CompletionStage<U> other, BiFunction<T, U, V> fn): Łączy wyniki dwóch future.allOf(CompletableFuture<?>... cfs): ZwracaCompletableFuture<Void>, który kończy się, gdy wszystkie przekazane future się zakończą.anyOf(CompletableFuture<?>... cfs): ZwracaCompletableFuture<Object>, który kończy się, gdy dowolny z przekazanych future się zakończył.
- Obsługa wyjątków:
exceptionally(Function<Throwable, T> fn): Obsługuje wyjątki, zwracając alternatywną wartość.handle(BiFunction<T, Throwable, U> fn): Obsługuje zarówno wynik, jak i wyjątek.
Przykład:
// Uruchomienie asynchronicznego zadania
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000); // Symulacja długiej pracy
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return "Wynik operacji asynchronicznej";
});
// Wykonanie działania po zakończeniu zadania (bez blokowania)
future.thenAccept(result -> {
System.out.println("Otrzymany wynik: " + result);
});
// Kolejne działanie zależne od pierwszego
future.thenApply(String::toUpperCase)
.thenAccept(upperCaseResult -> {
System.out.println("Wynik wielkimi literami: " + upperCaseResult);
});
// Oczekiwanie na zakończenie wszystkich zadań (w rzeczywistych aplikacjach zwykle unika się jawnego użycia get/join)
// future.join();
CompletableFuture jest potężnym narzędziem do pisania reaktywnego i nieblokującego kodu w Javie, znacznie upraszczając pracę z asynchronicznością w porównaniu z klasycznym interfejsem Future.