Is there a nice way to stop the repetition of task from within the task itself when running in a ScheduledExecutorService?
Lets say, I have the following task:
Future<?> f = scheduledExecutor.scheduleAtFixedRate(new Runnable() { int count = 0; public void run() { System.out.println(count++); if (count == 10) { // ??? cancel self } } }, 1, 1, TimeUnit.SECONDS);
From outside, it is easy to cancel via f.cancel(), but how can I stop the repetition at the specified place? (Passing the Future through an AtomicReference is not safe, because there is a potential window when the scheduleAtFixedRate returns f late and the variable is set late too, and the task itself might already run, seeing a null in the reference.)
Learn to cancel a task submitted to an executor service if the task still has to be executed and/or has not been completed yet. We can use the cancel() method of Future object that allows making the cancellation requests.
The cancel() method is used to cancel the timer task. The cancel() methods returns true when the task is scheduled for one-time execution and has not executed until now and returns false when the task was scheduled for one-time execution and has been executed already.
public interface ScheduledExecutorService extends ExecutorService. An ExecutorService that can schedule commands to run after a given delay, or to execute periodically. The schedule methods create tasks with various delays and return a task object that can be used to cancel or check execution.
ScheduledExecutorService is an ExecutorService which can schedule tasks to run after a delay, or to execute repeatedly with a fixed interval of time in between each execution. Tasks are executed asynchronously by a worker thread, and not by the thread handing the task to the ScheduledExecutorService .
When a repeating task throws an Exception or Error, it is placed in the Future and the task is not repeated again. You can throw a RuntimeException or Error of your choice.
Instead of using an anonymous inner class you can use a named class which can then have a property for the Future
object you get from the Executor
when you schedule a task.
abstract class FutureRunnable implements Runnable { private Future<?> future; /* Getter and Setter for future */ }
When you schedule a task you can then pass the Future
to the Runnable
.
FutureRunnable runnable = new FutureRunnable() { public void run() { if (/* abort condition */) getFuture().cancel(false); } }; Future<?> future = executor.scheduleAtFixedRate(runnable, ...); runnable.setFuture(future);
Maybe you will have to make sure, that the task is not executed before the Future
has been set, because otherwise you will get a NullPointerException
.
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