0Pricing
Java Academy · Lezione

Richieste asincrone

sendAsync e CompletableFuture

Richieste asincrone è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Richieste asincrone

Bloccare un thread per ogni chiamata HTTP spreca risorse. Il client HTTP del JDK offre sendAsync, che restituisce immediatamente un CompletableFuture ed esegue l'operazione su un esecutore in background.

In questo modo potete avviare molte richieste contemporaneamente e comporre i relativi risultati senza gestire manualmente i thread.

send e sendAsync

Le firme differiscono per il valore restituito:

  • send restituisce HttpResponse<T> e blocca, dichiarando IOException e InterruptedException.
  • sendAsync restituisce CompletableFuture<HttpResponse<T>> e non blocca mai; gli errori vengono resi disponibili tramite il future.

Una chiamata sendAsync di base

sendAsync accetta la stessa richiesta e lo stesso BodyHandler di send. Il future restituito viene completato quando la risposta è pronta.

import java.net.URI;
import java.net.http.*;
import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://example.com"))
            .build();
        CompletableFuture<HttpResponse<String>> future =
            client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("Request sent, future created");
    }
}

Trasformazione con thenApply

Usate thenApply per trasformare il risultato quando arriva, ad esempio estraendo il corpo dalla risposta.

L'operazione viene eseguita in modo sincrono sul thread che ha completato lo stage precedente.

import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> future =
            CompletableFuture.completedFuture("OK 200")
                .thenApply(body -> "Length=" + body.length());
        System.out.println(future.get());
    }
}

Consumo con thenAccept

Quando vi serve solo un effetto collaterale e nessun valore restituito, usate thenAccept. Accetta un Consumer e restituisce un CompletableFuture<Void>.

import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) throws Exception {
        CompletableFuture<Void> done =
            CompletableFuture.completedFuture("payload")
                .thenAccept(b -> System.out.println("Received: " + b));
        done.get();
    }
}

Blocco con join

Per attendere un risultato asincrono da main, chiamate join() (non controllata) oppure get() (controllata). In un server reale, invece di bloccare, comporreste gli stage.

join() racchiude gli errori in una CompletionException non controllata.

import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) {
        CompletableFuture<Integer> f =
            CompletableFuture.supplyAsync(() -> 21).thenApply(n -> n * 2);
        int result = f.join();
        System.out.println("Result: " + result);
    }
}

Gestione degli errori con exceptionally

exceptionally fornisce un valore di fallback quando uno stage non riesce, consentendo il recupero della pipeline.

In questo modo un flusso HTTP asincrono non si interrompe a causa di un errore di rete.

import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) {
        CompletableFuture<String> f = CompletableFuture
            .<String>supplyAsync(() -> { throw new RuntimeException("boom"); })
            .exceptionally(ex -> "fallback: " + ex.getMessage());
        System.out.println(f.join());
    }
}

Combinazione di due richieste

thenCombine attende due future indipendenti e ne unisce i risultati. Con l'HTTP asincrono, consente di recuperare due endpoint in parallelo e unire i relativi corpi.

import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) {
        CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> "Hello");
        CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> "World");
        String combined = a.thenCombine(b, (x, y) -> x + " " + y).join();
        System.out.println(combined);
    }
}

Avvio di molte richieste in parallelo

Per eseguire un gruppo di richieste, raccogliete ogni future in una lista, quindi usate CompletableFuture.allOf(...) per attenderle tutte.

allOf restituisce CompletableFuture<Void>; i singoli risultati vengono letti in seguito.

import java.util.*;
import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) {
        List<CompletableFuture<Integer>> futures = new ArrayList<>();
        for (int i = 1; i <= 3; i++) {
            int n = i;
            futures.add(CompletableFuture.supplyAsync(() -> n * n));
        }
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        for (var f : futures) System.out.println(f.join());
    }
}

Riepilogo del pattern asincrono

Una tipica pipeline HTTP asincrona è strutturata come segue:

  • client.sendAsync(req, BodyHandlers.ofString())
  • .thenApply(HttpResponse::body) per ottenere il corpo
  • .thenAccept(System.out::println) per utilizzarlo
  • .exceptionally(ex -> ...) per gestire il recupero

Nessun thread viene mai bloccato in attesa della rete.

Quando usare l'asincrono

Scegliete sendAsync quando effettuate molte chiamate contemporanee, distribuite le richieste su diversi servizi o eseguite il codice all'interno di un server reattivo/non bloccante. Scegliete send per script semplici e chiamate occasionali in cui il blocco non costituisce un problema.

Verifica rapida

Verificate la vostra comprensione delle richieste asincrone.

Riepilogo

Avete imparato a effettuare chiamate HTTP non bloccanti:

  • sendAsync restituisce un CompletableFuture invece di bloccare.
  • thenApply / thenAccept trasformano e utilizzano il risultato.
  • exceptionally fornisce un fallback in caso di errore.
  • thenCombine unisce due chiamate parallele; allOf attende un gruppo di chiamate.
  • L'asincronia è adatta ai server ad alta concorrenza e reattivi; la modalità sincrona è adatta agli script semplici.

Domande Frequenti

La lezione «Richieste asincrone» è gratuita?

Sì — il testo completo di «Richieste asincrone» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Richieste asincrone»?

sendAsync e CompletableFuture Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Richieste asincrone»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. java.net.http.HttpClient
  2. Richieste asincrone
  3. Corpi e intestazioni delle richieste
  4. Gestione delle risposte
← Torna a Java Academy