CompletableFuture автоматически отменяется, когда я получаю и выдается исключение? - PullRequest
1 голос
/ 04 октября 2019

Я делаю что-то вроде следующего в моем коде.

CompletableFuture<FOObar> f =  doSomething();
Foobar foo = f.get(timeout, TimeUnit.MILLISECONDS);

, если get выбрасывает любой Exception, будь то TimeoutException или иным образом, что произойдет с будущим. Это отменено по умолчанию, или я должен сделать

try {
f.get(timeout, TimeUnit.MILLISECONDS);
}
catch {
  f.cancel(true);
}

и, следовательно, будущее выпущено. если я не отменяю explicity, будущее будет зависеть от потока, что в конечном итоге приведет к голоданию, если все потоки застрянут в этом состоянии

Мне нужно заблокировать get, так как мне нужен foo выполнить дальнейшую логику.

1 Ответ

1 голос
/ 04 октября 2019

Согласно JavaDoc, при вызове get(timeout, unit) возможно 4 исключения:

  • CancellationException - если это будущее было отменено
  • ExecutionException - если это будущее завершено исключительно
  • InterruptedException - если текущий поток был прерван во время ожидания
  • TimeoutException - если время ожидания истекло

ExecutionException является наиболее простым: будущее завершено без исключения, что обычно означает, что задача завершилась с выдачей исключения (но это также может означать, что что-то еще завершило будущее с исключением).

последние 2 относятся к ожиданию самого вызова get() и указывают только на то, что будущее не было завершено, когда возникло исключение.

CancellationException указывает, что будущее было cancel()ed, но не указывает, выполняется ли задание по-прежнему.

Дело в том, что вызов cancel(boolean) по умолчанию не отменяет запущенное задание, даже когда аргументэто true:

Параметры

mayInterruptIfRunning - это значение не действует в этой реализации, поскольку прерывания не используются для управления обработкой.

Таким образом, по умолчанию не имеет значения, вызываете ли вы cancel() или нет, потому что это не повлияет на текущее задание.

Если вы хотите остановить запущенное задание, вам необходимо реализоватьконкретный механизм поддержки его в методе, который создает CompletableFuture (здесь doSomething()). Например, он может проверить, отменено ли возвращенное будущее, или предоставить какой-то другой механизм обратного вызова, чтобы остановить выполнение (например, установив где-нибудь флаг stop).

...