Синхронный VS асинхронный
Запрос может быть отправлен либо синхронно, либо асинхронно. Синхронный API блокирует до тех пор, пока Http-ответ не станет доступен
HttpResponse<String> response =
client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
Асинхронный API немедленно возвращается с CompletableFuture, который завершается с HttpResponse, когда он становится доступным. CompletableFuture был добавлен в Java 8 и поддерживает композитное асинхронное программирование.
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(response -> { System.out.println(response.statusCode());
return response; } )
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
Будущий объект
Будущее представляет собой результат асинхронных вычислений. Java Doc
Это означает, что это не синхронная функция, и что ваше предположение «Я ожидаю, что запрос будет отменен сразу после», будет верно только для синхронного метода.
Проверка отмены объекта Future
Существует полезный метод isCancelled()
, если вы хотите проверить, отменена ли ваша задача.
if(future.isCancelled()) {
// Future object is cancelled, do smth
} else {
// Future object is still running, do smth
}
sendAsync () возвращает объект CompletableFuture
Метод sendAsync()
возвращает CompletableFuture . Обратите внимание, что CompletableFuture
реализует интерфейс Future
.
Вы можете сделать что-то вроде:
client.sendAsync(request, BodyHandlers.ofString())
.thenAccept(response -> {
// do action when completed;
});
В техническом плане метод thenAccept
добавляет Consumer
, который вызывается, когда отклик становится доступным.
Почему метод отмены через CompeletableFuture не будет работать
Поскольку (в отличие от FutureTask
) этот класс не имеет прямого контроля над вычислениями, которые приводят к его завершению, отмена рассматривается как еще одна форма исключительного завершения. Метод отмены имеет тот же эффект, что и completeExceptionally(new CancellationException())
. Метод isCompletedExceptionally()
может использоваться для определения того, завершен ли CompletableFuture
каким-либо исключительным образом.
В случае исключительного завершения с CompletionException
, методы get()
и get(long, TimeUnit)
выдают ExecutionException
по той же причине, что и соответствующая CompletionException
. Чтобы упростить использование в большинстве контекстов, этот класс также определяет методы join()
и getNow (T), которые вместо этого напрямую выбрасывают CompletionException
в этих случаях.
Другими словами
Метод cancel()
не использует прерывания для отмены, и поэтому он не работает. Вы должны использовать completeExceptionally(new CancellationException())
Ссылка