I have a ScheduledExecutorService
that times a few different task periodically with scheduleAtFixedRate(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?
You can cancel a future using Future. cancel() method. It attempts to cancel the execution of the task and returns true if it is cancelled successfully, otherwise, it returns false. The cancel() method accepts a boolean argument - mayInterruptIfRunning .
You can cancel the task submitted to ExecutorService by simply calling the cancel method on the future submitted when the task is submitted.
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.
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()
.
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