logo

Cos'è CompletableFuture?

UN CompltableFuture viene utilizzato per la programmazione asincrona. Programmazione asincrona significa scrivere codice non bloccante. Esegue un'attività su un thread separato rispetto al thread principale dell'applicazione e notifica al thread principale il suo avanzamento, completamento o errore.

In questo modo il thread principale non si blocca né attende il completamento dell'attività. Altre attività vengono eseguite in parallelo. Il parallelismo migliora le prestazioni del programma.

Un CompletableFuture è una classe in Java. Appartiene al pacchetto java.util.cocurrent. Implementa l'interfaccia CompletionStage e Future.

Fase di completamento

  • Esegue un'azione e restituisce un valore al termine di un'altra fase di completamento.
  • Un modello per un'attività che può attivare altre attività.

Quindi, è un elemento di una catena.

Quando più di un thread tenta di completare, completare in via eccezionale o annullare un CompletableFuture, solo uno di essi riesce.

array di byte per stringere java

Futuro vs. CompletabileFuturo

Un CompletableFuture è un'estensione dell'API Future di Java introdotta in Java 8.

Un Future viene utilizzato per la programmazione asincrona. Fornisce due metodi, isDone() e get(). I metodi recuperano il risultato del calcolo una volta completato.

Limitazioni del futuro

  • Un futuro non può essere reciprocamente completo.
  • Non possiamo eseguire ulteriori azioni sul risultato di un Futuro senza bloccare.
  • Il futuro non ha alcuna gestione delle eccezioni.
  • Non possiamo combinare più futuri.

Il futuro ha così tante limitazioni, ecco perché abbiamo CompletableFuture. CompletableFuture fornisce un'ampia gamma di metodi per creare più Future, concatenare e combinare. Dispone inoltre di un supporto completo per la gestione delle eccezioni.

Creare un futuro completabile

Possiamo creare un CompletableFuture solo utilizzando il seguente costruttore senza argomenti.

 CompletableFuture CompletableFuture = new CompletableFuture(); 

Esempio

I metodi CompletableFuture più utilizzati sono:

    supplyAsync():Completa il suo lavoro in modo asincrono. Il risultato di fornitore viene eseguito da un'attività da ForkJoinPool.commonPool() per impostazione predefinita. Il metodo supplyAsync() restituisce CompletableFuture su cui possiamo applicare altri metodi.quindi Applica():Il metodo accetta la funzione come argomento. Restituisce un nuovo CompletableStage quando questa fase viene completata normalmente. La nuova fase viene utilizzata come argomento per la funzione fornita.giuntura():il metodo restituisce il valore del risultato una volta completato. Genera anche una CompletionException (eccezione non controllata) se completata in modo eccezionale.
 import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; public class CompletableFutureExample1 { public static void main(String[] args) { try { List list = Arrays.asList(5,9,14); list.stream().map(num->CompletableFuture.supplyAsync(()->getNumber(num))).map(CompletableFuture->CompletableFuture.thenApply(n- >n*n)).map(t->t.join()).forEach(s->System.out.println(s)); } catch (Exception e) { e.printStackTrace(); } } private static int getNumber(int a) { return a*a; } } 

Produzione:

CompletabileFuturo in Java

Gestione delle eccezioni di CompletableFuture

Consideriamo la seguente figura, che rappresenta i cinque CF:

b più albero
CompletabileFuturo in Java

Supponiamo che cinque CF in esecuzione e CF21 sollevino un'eccezione, quindi tutti i CF dipendenti (CF31 e CF41) sono in errore. Significa che:

  • La chiamata al metodo isCompletedExceptionally() restituisce true.
  • La chiamata a get() lancia un'ExecutionException che causa l'eccezione root.

Consideriamo la figura seguente, in cui abbiamo creato CF30 con un'eccezione.

CompletabileFuturo in Java

Quando CF21 viene eseguito normalmente, CF30 trasmette semplicemente il valore. Se solleva un'eccezione, CF30 la gestisce e genera valore per CF31.

Esistono tre metodi per gestire un'eccezione:

 public CompletableFuture exceptionally(Function function); public CompletableFuture hadle(BiFunction bifunction); public CompletableFuture whenComplete(BiConsumer action);