Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop a periodic task from within the task itself running in a ScheduledExecutorService

Tags:

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.)

like image 701
akarnokd Avatar asked Feb 05 '11 21:02

akarnokd


People also ask

How do I stop scheduled executor service?

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.

How do I stop a scheduler in Java?

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.

What is a ScheduledExecutorService?

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.

Is ScheduledExecutorService an async?

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 .


2 Answers

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.

like image 53
Peter Lawrey Avatar answered Sep 28 '22 01:09

Peter Lawrey


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.

like image 22
Reboot Avatar answered Sep 28 '22 00:09

Reboot