The Javadocs for Java's ScheduledThreadPoolExecutor
state the following:
When a submitted task is cancelled before it is run, execution is suppressed. By default, such a cancelled task is not automatically removed from the work queue until its delay elapses. While this enables further inspection and monitoring, it may also cause unbounded retention of cancelled tasks. To avoid this, set
setRemoveOnCancelPolicy(boolean)
to true, which causes tasks to be immediately removed from the work queue at time of cancellation.
I interpret this as meaning that
ScheduledFuture
returned by the ScheduledThreadPoolExecutor
when you "schedule" a task, the task will not be truly removed from the queue until the duration that we scheduled it has fully elapsed.ScheduledThreadPoolExecutor
's removeOnCancelPolicy
to true, we remove the task from the work queue immediately, rather than waiting for the scheduled duration until the task is taken off of the work queue.Are there any consequences to setting the removeOnCancelPolicy
to true?
I'm considering doing it in order to make sure that the work queue doesn't get too large and take up too much memory, but I'm confused as to why this policy isn't on by default.
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
).
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;
}
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.
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.
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).
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.
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".
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.