Java Academy · Урок

Асинхронные запросы

sendAsync и CompletableFuture

Урок 2 из 413 шагов

«Асинхронные запросы» — бесплатный урок Java Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Асинхронные запросы

Блокировка потока при каждом HTTP-вызове приводит к неэффективному использованию потоков. HTTP-клиент JDK предоставляет sendAsync, который немедленно возвращает CompletableFuture и выполняет работу в фоновом потоке выполнения.

Это позволяет одновременно отправлять множество запросов и объединять их результаты без ручного управления потоками.

send и sendAsync

Сигнатуры различаются возвращаемым значением:

  • send возвращает HttpResponse<T> и блокирует поток, объявляя IOException и InterruptedException.
  • sendAsync возвращает CompletableFuture<HttpResponse<T>> и никогда не блокирует поток; ошибки передаются через этот объект.

Простой вызов sendAsync

sendAsync принимает тот же запрос и BodyHandler, что и send. Возвращаемый объект завершается, когда ответ готов.

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");
    }
}

Преобразование с помощью thenApply

Используйте thenApply, чтобы преобразовать результат после его получения — например, извлечь тело из ответа.

Этот код выполняется синхронно в потоке, завершившем предыдущий этап.

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());
    }
}

Обработка с помощью thenAccept

Если требуется только побочный эффект и возвращаемое значение не нужно, используйте thenAccept. Он принимает Consumer и возвращает 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();
    }
}

Ожидание с помощью join

Чтобы дождаться асинхронного результата из main, вызовите join() (без проверки) или get() (с проверкой). В настоящем сервере следует объединять этапы, а не блокировать поток.

join() оборачивает сбои в непроверяемое 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);
    }
}

Обработка ошибок с помощью exceptionally

exceptionally предоставляет резервное значение, если этап завершился с ошибкой, восстанавливая конвейер.

Так асинхронный поток выполнения HTTP-запроса не прекращается из-за сетевой ошибки.

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());
    }
}

Объединение двух запросов

thenCombine ожидает завершения двух независимых асинхронных результатов и объединяет их. При асинхронной работе с HTTP это позволяет параллельно получить данные из двух конечных точек и объединить тела ответов.

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);
    }
}

Параллельный запуск множества запросов

Чтобы выполнить набор запросов, соберите каждый объект CompletableFuture в список, а затем используйте CompletableFuture.allOf(...), чтобы дождаться завершения всех запросов.

allOf возвращает CompletableFuture<Void>; отдельные результаты считываются после этого.

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());
    }
}

Итоги асинхронного шаблона

Типичный конвейер асинхронных HTTP-операций выглядит так:

  • client.sendAsync(req, BodyHandlers.ofString())
  • .thenApply(HttpResponse::body) для получения тела
  • .thenAccept(System.out::println) для его обработки
  • .exceptionally(ex -> ...) для восстановления после ошибки

Ожидание сети никогда не блокирует поток.

Когда выбирать асинхронность

Выбирайте sendAsync, когда выполняете много параллельных вызовов, обращаетесь к нескольким службам или работаете внутри реактивного/неблокирующего сервера. Выбирайте send для простых скриптов и разовых вызовов, где блокировка допустима.

Быстрая проверка

Проверьте, насколько хорошо вы поняли работу с асинхронными запросами.

Итоги

Вы научились выполнять неблокирующие HTTP-вызовы:

  • sendAsync возвращает CompletableFuture вместо блокировки.
  • thenApply / thenAccept преобразуют результат и обрабатывают его.
  • exceptionally предоставляет резервное значение при сбое.
  • thenCombine объединяет два параллельных вызова; allOf ожидает завершения набора запросов.
  • Асинхронный подход подходит для высококонкурентных и реактивных серверов, а синхронный — для простых скриптов.
Можно начать бесплатно

Изучай Java с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
104
Уроки
374

Часто задаваемые вопросы

Урок «Асинхронные запросы» бесплатный?

Да — полный текст урока «Асинхронные запросы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Асинхронные запросы»?

sendAsync и CompletableFuture Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Асинхронные запросы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. java.net.http.HttpClient
  2. Асинхронные запросы
  3. Тела запросов и заголовки
  4. Обработка ответов
← Назад к Java Academy