Как отменить задачу в Java ExecutorService

Научитесь отменять задачу, отправленную в службу исполнителя, если задача все еще должна быть выполнена и/или еще не завершена. Мы можем использовать метод cancel() объекта Future, который позволяет делать запросы на отмену.

1. Будущее API Cancel()

Метод Future.cancel() принимает один аргумент типа boolean.

boolean cancel(boolean mayInterruptIfRunning);

В зависимости от значения mayInterruptIfRunning и статуса задачи, переданной исполнителю, поведение этого метода различается:

  • Если задача была выполнена или отменена ранее, или ее невозможно отменить по какой-либо другой причине, метод вернет значение false и задача не будет отменена.
  • Если задача ожидает в очереди начала выполнения, задача будет отменена и никогда не начнет свое выполнение. Метод вернет true.
  • Если задача уже запущена и значение параметра mayInterruptIfRunning равно true, InterruptedException отправляется потоку в попытке остановить задачу. Поэтому задача должна периодически проверять статус прерывания и прекращать работу, если он равен true.
  • Если задача уже запущена и значение параметра mayInterruptIfRunning равно false, поток НЕ будет прерван.

См. также: Как завершить работу ExecutorService

2. Отмена задачи в очереди ожидания

В этом примере у нас есть задача, которая будет выполнена через минуту от запланированного времени. После планирования мы проверяем статус задачи с помощью метода isDone(), который возвращает false, поскольку задача еще не завершена.

Затем мы отменяем задачу и проверяем ее статус с помощью методов isCancelled() и isDone().

import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.ScheduledFuture;import java.util.concurrent.TimeUnit;public class CancelATask {public static void main(String[] args) {ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);ScheduledFuture<?> future = executor.schedule(() -> { System.out.println("Some Task"); }, 5, TimeUnit.SECONDS);System.out.println("Before Cancel - Task is done : " + future.isDone());System.out.println("Before Cancel - Task is cancel : " + future.isCancelled());if(future.isDone() == false) {future.cancel(false);}System.out.println("Before Cancel - Task is done : " + future.isDone());System.out.println("Before Cancel - Task is cancel : " + future.isCancelled());executor.shutdown();}}

Вывод программы.

 Перед отменой — задача выполнена: falseПеред отменой — задача отменена: falseЗадача отменена: правдаЗадача выполнена: верно

Очевидно, что после отмены задачи ее статус «Выполнено» также остается верным.

3. Отмена задачи, находящейся в процессе выполнения

Если задача уже начала выполнение, то мы не можем остановить ее выполнение, как правило. Мы должны прервать поток и позволить задаче остановить себя.

 будущее.отмена(истина)

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

 если(Поток.прерван()) {выдать новое исключение InterruptedException();}

Наконец, отмените выполнение задачи, вернувшись из потока.

try {//task code} catch(InterruptedException e) {Thread.currentThread().interrupt();return;}

4. Заключение

API Future.cancel() очень полезен для отмены задачи, которая еще не началась или началась, но не завершена. Завершенная задача не может быть отменена никаким образом.

Пишите мне в комментариях свои вопросы о том, как отменить задачу, отправленную исполнителю в Java.

Исходный код на Github

Прокрутить вверх