Sobes.tech
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 zwraca CompletableFuture z jego wynikiem.
    • runAsync(Runnable runnable): Uruchamia Runnable asynchronicznie i zwraca CompletableFuture<Void>.
    • completedFuture(T value): Tworzy już zakończony CompletableFuture z 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): Zwraca CompletableFuture<Void>, który kończy się, gdy wszystkie przekazane future się zakończą.
    • anyOf(CompletableFuture<?>... cfs): Zwraca CompletableFuture<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.