How to remove a task from ScheduledExecutorService?
Solution 1
Simply cancel the future returned by scheduledAtFixedRate()
:
// Create the scheduler
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
// Create the task to execute
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
};
// Schedule the task such that it will be executed every second
ScheduledFuture<?> scheduledFuture =
scheduledExecutorService.scheduleAtFixedRate(r, 1L, 1L, TimeUnit.SECONDS);
// Wait 5 seconds
Thread.sleep(5000L);
// Cancel the task
scheduledFuture.cancel(false);
Another thing to note is that cancel does not remove the task from scheduler. All it ensures is that isDone
method always return true
. This may lead to memory leaks if you keep adding such tasks. For e.g.: if you start a task based on some client activity or UI button click, repeat it n-times and exit. If that button is clicked too many times, you might end up with big pool of threads that cannot be garbage collected as scheduler still has a reference.
You may want to use setRemoveOnCancelPolicy(true)
in ScheduledThreadPoolExecutor
class available in Java 7 onwards. For backward compatibility, default is set to false.
Solution 2
If your ScheduledExecutorService
instance extends ThreadPoolExecutor
(e.g. ScheduledThreadPoolExecutor
), you could use remove(Runnable)
(but see the note in its javadoc: "It may fail to remove tasks that have been converted into other forms before being placed on the internal queue.") or purge()
.
thepoosh
A java (mostly) developer at Freightos interested in Android, Flutter, Java, GCP,k8s and anything I can wrap my head around
Updated on July 05, 2022Comments
-
thepoosh almost 2 years
I have a
ScheduledExecutorService
that times a few different task periodically withscheduleAtFixedRate(Runnable, INIT_DELAY, ACTION_DELAY, TimeUnit.SECONDS);
I also have a different
Runnable
that I'm using with this scheduler. the problem starts when I want to remove one of the tasks from the scheduler.Is there a way to do this?
Am I doing the right thing using one scheduler for different tasks? What is the best way to implement this?
-
Mark Jeronimus over 8 yearsNote to people using
newSingleThreadScheduledExecutor()
as it doesn't expose the inner executor: Create an executor yourself, set the property, then wrap it withExecutors.unconfigurableScheduledExecutorService()
. -
JohnyTex over 6 yearsWhy I can't reuse it? Why so hard to get cancelled tasks removed?
-
falvojr over 6 yearsTo use
setRemoveOnCancelPolicy(true)
, see the explanation of the instantiation variants forScheduledThreadPoolExecutor
here: stackoverflow.com/a/36748183/3072570. -
thepoosh over 6 yearsthanks for the answer, at the time this method didn't exist in
Executor