Cancelling
A task is cancelled by invoking method Future.cancel(boolean).
So suppose you scheduled a task by schedule which implies a delay on the queue until execution starts:
Creates and executes a one-shot action that becomes enabled after the given delay.
Runnable task = new Callable<String>() {
public String call() { return "Hello Future World!"; }
};
Future<String> future = executor.schedule(task, 50L, TimeUnit.SECONDS);
future.cancel(true);
The task is pushed to the work queue of this executor and waits there for execution (at least the specified delay of 50L, SECONDS).
During this duration, you can cancel it. But depending on the removeOnCancelPolicy policy it either remains on the queue until execution would start (false) or it will be removed immediately (true).
Purge (related design considerations)
- What happens if we
cancel a ScheduledFutureTask?
The behaviour depends on policy removeOnCancel of class ScheduledThreadPoolExecutor - see implementation of this inner-class method ScheduledFutureTask.cancel
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= 0)
remove(this);
return cancelled;
}
- What happens if a task was only cancelled, but not removed (by policy)?
The design considers this. See the parent class ThreadPoolExecutor's methods remove(runnable) and especially purge():
Tries to remove from the work queue all Future tasks that have been cancelled. This method can be useful as a storage reclamation operation, that has no other impact on functionality. Cancelled tasks are never executed, but may accumulate in work queues until worker threads can actively remove them. Invoking this method instead tries to remove them now. However, this method may fail to remove tasks in the presence of interference by other threads.
Queues as scarce resource
A queue, especially a blocking-queue is somehow limited (e.g. in capacity: holds max items) why you should always strive to keep them short, not too much work load queued up, process tasks as fast as possible.
Thus the docs warned about removeOnCancelPolicy set false:
may also cause unbounded retention of cancelled tasks
So the policy has impact on the queue, its fill-level (max capacity), possible rejection of further submitted tasks, etc.
You could experiment the behaviour of this policy, by inspecting the underlying BlockingQueue of your executor: its size, the elements of Future on it. Their isCancelled state, etc.
Use case: view cancelled tasks and beyond
If the queue retains cancelled tasks then this allows to put the user in control (Usability principle), re-/un-do effort can be reduced, rescheduling can be a useful feature (as following example illustrates).
Cancelling a task
Suppose you have a report-scheduler with a some UI. When a user schedules a report then the report will be submitted (with some delay) to your executor/queue.
Given the user scheduled a report and a second later recognizes that it got the wrong parameters. Because they will cause the report to run very long, they immediately cancel the scheduled report. Lucky they were, that it wasn't too late.
Now: This means additional effort, because the wrong parameters must be corrected or reentered and the report scheduled again.
Rescheduling a task
Instead of entering all the parameters again, they want to reschedule the existing canceled one, and just modify a few parameters before clicking on "Submit" or "Schedule".
Not forgotten, forgiven!
If the policy removeOnCancelPolicy is set to false
this enables further inspection and monitoring
A view lists all tasks, filtered by status (canceled, scheduled, running, completed, etc.), so that the canceled one can be selected and its details (schedule, parameters) can be viewed. Additionally the action "Reschedule" makes it easy to submit it again.