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.
@hc_dev's answer is great and explains many of the consequences of setting removeOnCancelPolicy to true, but there's one more consequence of setting that value to true - the concurrency of the blocking queue within your ScheduledExecutorService may be affected.
By default, the ScheduledExecutorService created by the Executors.newScheduledThreadPool factory method uses a ScheduledThreadPoolExecutor.DelayedWorkQueue as its work queue. This work queue consists of one array contained within it, guarded by one lock. This means that while one thread is removeing tasks from the ScheduledThreadPoolExecutor.DelayedWorkQueue, other threads will have to wait in order to push or pop anything from the work queue, each time that a task is cancelled. So, setting a removeOnCancelPolicy will raise the contention for the locks on the blocking queue and lower the concurrency of the queue.
The Javadocs have this to say about ScheduledThreadPoolExecutor.DelayedWorkQueue's performance with it's remove method:
A DelayedWorkQueue is based on a heap-based data structure like those in DelayQueue and PriorityQueue, except that every ScheduledFutureTask also records its index into the heap array. This eliminates the need to find a task upon cancellation, greatly speeding up removal (down from O(n) to O(log n)), and reducing garbage retention that would otherwise occur by waiting for the element to rise to top before clearing.
So, the performance of the remove method is quite good, and scales well with many entries in the queue, but this is something to keep in mind.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With