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, dichiarandoIOExceptioneInterruptedException. - 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
CompletableFutureinvece 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
- java.net.http.HttpClient
- Richieste asincrone
- Corpi e intestazioni delle richieste
- Gestione delle risposte