Подтвердить что ты не робот

Concurrency - прерывание Будущего без его отмены

Есть ли способ прервать будущее без его отмены?

API java doc:

boolean отменить (boolean mayInterruptIfRunning)

Попытка отменить выполнение этой задачи. Эта попытка потерпит неудачу, если задача уже завершена, уже отменена или не может быть отменено по другой причине. В случае успеха, и эта задача не начинается с момента вызова cancel, эта задача никогда не должна запускаться. Если задача уже началось, тогда параметр mayInterruptIfRunning определяет, должен ли поток, выполняющий эту задачу, прерван в попытке остановить выполнение задачи.

Чтобы захватить прерывание, мы должны правильно поймать прерванное исключение или проверить метод isInterrupted() в методе Runnable/Callable.

Но нет возможности прервать запуск Будущего с использованием интерфейса Future.

Поскольку все потоки находятся в пуле службы "Исполнитель", никто не может выполнять thread.interrupt(). Поэтому предполагается, что любое прерывание произойдет только тогда, когда будет отменено будущее или пул потоков завершен?

Я пытаюсь понять, почему в интерфейсе Future нет метода прерывания. Любая помощь будет принята с благодарностью

4b9b3361

Ответ 1

Причина заключается в различии в абстракции, которая является Будущим и конкретным исполнением в потоке. Мы не можем сказать, связано ли будущее с одним потоком или несколькими потоками. Будущее может запускать новые потоки, запускать новые фьючерсы и т.д.

Рассмотрим эти абстракции как взаимодействия между клиентским кодом и исполнителем фьючерсов. Понятно, что имеет смысл сказать "отменить эту задачу, которую я просил вас сделать", потому что ваша задача была отменена. Я могу заняться этим, или я, возможно, еще не начал его, или он может быть закончен, но все в порядке, я отменим его, если вы захотите. Итак, почему у нас есть метод отмены.

С другой стороны, не имеет смысла говорить "прервать свою задачу". Из-за развязки между результатом действия (Будущее) и моделью исполнения (например, Исполнителем) клиент не знает, какие действия предпринимаются для выполнения задачи. Как тогда можно ожидать, что клиент узнает, когда прерывание подходит, требуется или даже поддерживается.

Ответ 2

В любом случае вы можете использовать тайм-аут, поэтому вы прерываете свое ожидание.

get(long timeout, TimeUnit unit) 

Ответ 3

Для этого есть полезные возможности.

Так как проблема с API будущего заключается в том, что она не предоставляет возможности , чтобы обнаружить, что выполнение остановлено. isCancelled() и isDone() будут оба возвращать true, даже если выполнение Callable продолжается.

Так что это действительно не об уровне абстракции API будущего на данном этапе. Но это неспособность идентифицировать прекращение задачи. Или иначе, неспособность дифференцировать отменить запрос и завершенное отменить действие.

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