← Назад к вопросам

Метод get у CompletableFuture блокирующий или неблокирующий

2.0 Middle🔥 141 комментариев
#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Метод get() у CompletableFuture — блокирующий

Метод get() у CompletableFuture является БЛОКИРУЮЩИМ методом. Это означает, что поток, вызвавший get(), будет остановлен (заблокирован) и ждать, пока асинхронная операция завершится.

Как работает get()

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(2000); // Имитируем длительную операцию
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    return "Результат";
});

System.out.println("Начало ожидания");
String result = future.get(); // БЛОКИРУЕТ поток на 2 секунды
System.out.println("Результат: " + result);

В примере выше вызов future.get() блокирует текущий поток до завершения асинхронной операции.

Различие с CompletionStage

CompletableFuture наследует CompletionStage и предоставляет два подхода:

1. Блокирующие методы:

future.get();                           // Блокирует бесконечно
future.get(5, TimeUnit.SECONDS);        // Блокирует максимум 5 секунд
future.join();                          // Блокирует, выбрасывает unchecked exception

2. Неблокирующие методы (callbacks):

future.thenApply(result -> result.toUpperCase())    // Неблокирующий
      .thenAccept(System.out::println);              // Неблокирующий

future.whenComplete((result, exception) -> {
    if (exception == null) {
        System.out.println("Успешно: " + result);
    } else {
        System.out.println("Ошибка: " + exception);
    }
});  // Неблокирующий

Когда использовать get()?

Использовать get():

  • Когда нужно обязательно получить результат перед продолжением
  • В main методе или unit тестах
  • Когда логика зависит от результата
public void processData() throws ExecutionException, InterruptedException {
    CompletableFuture<Data> future = fetchDataAsync();
    Data data = future.get(); // OK здесь
    System.out.println(data);
}

Избегать get():

  • В асинхронном коде (используй callbacks)
  • В HTTP request handlers или servlet контексте
  • Когда нужна высокая пропускная способность

Обработка исключений

try {
    String result = future.get(3, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    System.out.println("Операция заняла слишком много времени");
    future.cancel(true); // Отменить операцию
} catch (ExecutionException e) {
    System.out.println("Ошибка при выполнении: " + e.getCause());
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    System.out.println("Поток был прерван");
}

Вывод

Метод get() — это блокирующий способ получить результат CompletableFuture. В современном асинхронном коде рекомендуется использовать неблокирующие методы вроде thenApply(), thenAccept() и whenComplete().