1. Future cancel() API
The Future.cancel() method takes one argument of typeboolean
boolean cancel(boolean mayInterruptIfRunning);
Depending on the value of mayInterruptIfRunning
and the status of the task submitted to the executor, the behavior of this method is different:
- If the task has been completed or has been canceled earlier, or it can’t be cancelled due to any other reason, the method will return the
false
value and the task won’t be canceled. - If the task is waiting in the queue to begin execution, the task will be canceled and will never begin its execution. The method will return
true
. - If the task is already running and the value of
mayInterruptIfRunning
the parameter istrue
, Interrupted Exception is sent to the thread in an attempt to stop the task. Therefore, task must periodically check for interrupt status and stop working if it is true. - If the task is already running and the value of
mayInterruptIfRunning
the parameter isfalse
, the thread will NOT be interrupted.
2. Cancelling a Task in Waiting Queue
In this example, we have a task that will be executed after a minute from the scheduled time. After scheduling, we check the status of the task using isDone() method which returns false
because the task is not completed yet.
Then we cancel the task and check the status of the task using isCancelled()
and isDone()
methods, both.
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(); } }
Output:
Before Cancel - Task is done : false Before Cancel - Task is cancel : false Task is cancelled : true Task is done : true
Clearly, after the task is canceled, the done status of the task is also true
.
3. Cancelling a Task in Execution
If the task has already started execution, then we cannot stop its execution, normally. We must interrupt the thread and let the task stop itself.
future.cancel(true)
An example of handling the interrupt inside the thread is as follows. Use this code in the task to check the interrupt status periodically.
if (Thread.interrupted()) { throw new InterruptedException(); }
Finally, cancel the task execution by returning from the thread.
try { //task code } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; }
4. Conclusion
The Future.cancel() API is very useful in cancelling a task that has either not started yet, or has started but not completed. A completed task can’t be cancelled in any way.
Drop me your questions in the comments regarding how to cancel a task submitted to executor in Java.
Leave a Reply