← Назад к вопросам
Метод 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().