Asynchrone Anfragen
sendAsync und CompletableFuture
Asynchrone Anfragen ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Asynchrone Anfragen
Bei jedem HTTP-Aufruf zu blockieren, verschwendet Threads. Der JDK-HTTP-Client bietet sendAsync, das sofort ein CompletableFuture zurückgibt und die Arbeit in einem Hintergrund-Executor ausführt.
So können Sie viele Anfragen gleichzeitig starten und ihre Ergebnisse verknüpfen, ohne Threads manuell verwalten zu müssen.
send und sendAsync
Die Signaturen unterscheiden sich in ihrem Rückgabewert:
- send gibt
HttpResponse<T>zurück und blockiert. Dabei werdenIOExceptionundInterruptedExceptiondeklariert. - sendAsync gibt
CompletableFuture<HttpResponse<T>>zurück und blockiert niemals; Fehler werden über das Future sichtbar.
Ein einfacher sendAsync-Aufruf
sendAsync akzeptiert dieselbe Anfrage und denselben BodyHandler wie send. Das zurückgegebene Future wird abgeschlossen, sobald die Antwort bereitsteht.
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");
}
}Mit thenApply transformieren
Verwenden Sie thenApply, um das Ergebnis nach seinem Eintreffen zu transformieren — beispielsweise, um den Body aus der Antwort zu extrahieren.
Dies wird synchron in dem Thread ausgeführt, der die vorherige Stufe abgeschlossen hat.
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());
}
}Mit thenAccept verarbeiten
Wenn Sie nur einen Seiteneffekt und keinen Rückgabewert benötigen, verwenden Sie thenAccept. Die Methode akzeptiert einen Consumer und liefert ein 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();
}
}Mit join blockieren
Um in main auf ein asynchrones Ergebnis zu warten, rufen Sie join() (ungeprüft) oder get() (geprüft) auf. In einem echten Server würden Sie Stufen verknüpfen, statt zu blockieren.
join() verpackt Fehler in eine ungeprüfte CompletionException.
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);
}
}Fehler mit exceptionally behandeln
exceptionally stellt einen Ersatzwert bereit, wenn eine Stufe fehlschlägt, und setzt so die Pipeline fort.
So verhindern Sie, dass ein asynchroner HTTP-Ablauf bei einem Netzwerkfehler abbricht.
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());
}
}Zwei Anfragen kombinieren
thenCombine wartet auf zwei unabhängige Futures und führt ihre Ergebnisse zusammen. Bei asynchronem HTTP können Sie damit zwei Endpunkte parallel abfragen und die Bodys zusammenführen.
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);
}
}Viele Anfragen parallel starten
Um einen Stapel von Anfragen auszuführen, sammeln Sie jedes Future in einer Liste und verwenden anschließend CompletableFuture.allOf(...), um auf alle zu warten.
allOf gibt CompletableFuture<Void> zurück; die einzelnen Ergebnisse lesen Sie anschließend aus.
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());
}
}Zusammenfassung des asynchronen Musters
Eine typische asynchrone HTTP-Pipeline sieht so aus:
client.sendAsync(req, BodyHandlers.ofString()).thenApply(HttpResponse::body), um den Body abzurufen.thenAccept(System.out::println), um ihn zu verarbeiten.exceptionally(ex -> ...), um Fehler abzufangen
Es wird zu keinem Zeitpunkt ein Thread blockiert, der auf das Netzwerk wartet.
Wann Sie asynchron arbeiten sollten
Wählen Sie sendAsync, wenn Sie viele gleichzeitige Aufrufe durchführen, mehrere Services parallel ansprechen oder innerhalb eines reaktiven bzw. nicht blockierenden Servers arbeiten. Wählen Sie send für einfache Skripte und einmalige Aufrufe, bei denen Blockieren unproblematisch ist.
Kurztest
Überprüfen Sie Ihr Verständnis asynchroner Anfragen.
Zusammenfassung
Sie haben gelernt, nicht blockierende HTTP-Aufrufe auszuführen:
- sendAsync gibt ein
CompletableFuturezurück, statt zu blockieren. - thenApply / thenAccept transformieren das Ergebnis und verarbeiten es.
- exceptionally stellt im Fehlerfall einen Ersatzwert bereit.
- thenCombine führt zwei parallele Aufrufe zusammen; allOf wartet auf einen Stapel von Aufrufen.
- Asynchronität eignet sich für hochgradig nebenläufige und reaktive Server; Synchronität für einfache Skripte.
Häufig gestellte Fragen
Ist die Lektion „Asynchrone Anfragen“ kostenlos?
Ja — der vollständige Text von „Asynchrone Anfragen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Asynchrone Anfragen“?
sendAsync und CompletableFuture Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Java Academy zu starten?
Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Asynchrone Anfragen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?
Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- java.net.http.HttpClient
- Asynchrone Anfragen
- Request-Bodies und Header
- Antworten verarbeiten