ТЛ; др;Future.cancel(false)
полезен только для того, чтобы избежать запуска задач, которые еще не были запущены.
Есть две важные вещи, которые нужно понять относительно параллелизма и отмены.
Во-первых, в Java отмена является чисто кооперативной.Java сигнализирует о запросе отмены, используя методы блокировки InterruptedExcetions и устанавливая флаг в Thread.Реализация задачи отвечает за уведомление о запросе отмены и отмену самого себя.Брайан Гетц объясняет прерывание в своем посте Работа с InterruptedException .Не все реализации задач будут правильно обрабатывать прерывания.
Второе, на что следует обратить внимание, это то, что объект Future является заполнителем для результатов выполнения задачи в будущем.Если у вас не запущено много потоков, возможно, что задача начинает выполняться сразу, но также возможно, что все потоки уже используются, и задача должна ждать.То, что у вас есть ссылка на объект Future, не означает, что соответствующая задача фактически запущена.Это своего рода резервирование.
У вас есть объект Future, но задача может находиться в одном из следующих состояний:
- Ожидание.Например, он может находиться в очереди других задач, ожидающих времени процессора.
- Выполняется.
- Завершено.
Если ваша задача находится в первом состоянии «Ожидание», то и Future.cancel(true)
, и Future.cancel(false)
пометят будущее как отмененное.Задача остается в очереди задач для выполнения, но когда исполнитель попадает к задаче, он замечает отмененный флаг и пропускает его.
Если ваша задача находится в третьем состоянии «Завершено», то оба значения Future.cancel(true)
иFuture.cancel(false)
верните false и ничего не делайте.Это имеет смысл, потому что они уже сделаны, и нет способа отменить их.
Флаг mayInterruptIfRunning
важен, только если ваша задача находится во втором состоянии «Выполняется».
Если ваша задача выполняется и mayInterruptIfRunning
имеет значение false, то исполнитель не выполняетчто угодно и позволяет завершить задачу.
Если ваша задача выполняется и mayInterruptIfRunning
имеет значение true, то исполнитель прервет задачу.Но помните немного о совместной отмене - чтобы прерывание работало, должна быть реализована задача обработки отмены.
Резюме:
Future.cancel(true)
подходит, когда:
- Future представляет собой долгосрочную задачу, которая, как известно, была реализована для обработки прерываний.
Future.cancel(false)
будет правильным:
- Реализация задачине может обработать прерывание.
- Неизвестно, поддерживает ли реализация задачи отмену.
- Вы готовы дождаться завершения уже запущенных задач.