Scheduling tasks using Concurrency API

Oftentimes in Java, there is a need to schedule a task to happen at some future time. Sometimes tasks must be scheduled to happen repeatedly, at some set interval. The ScheduledExecutorService, which is a subinterface of ExecutorService, can be used for just such tasks.

Like ExecutorService, developer obtains an instance of ScheduledExecutorService using a factory method in the Executors class, like in the following snippet :

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

ScheduledExecutorService methods are listed in the following table :

Method Name Description
schedule(Callable<V> callable, long delay, TimeUnit unit) Creates and executes a Callable task after the given delay
schedule(Runnable command, long delay, TimeUnit unit) Creates and executes a Runnable task after the given delay
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) Creates and executes a Runnable task after the given initial delay, creating a new task every period value that passes
scheduledAtDixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) Creates and executes a Runnable task after the given initial delay and subsequently with the given delay between the termination of one execution and the commencement of the next

These methods are among the most convenient in the Concurrency API, as they perform relatively complex tasks with a single line of code. The delay and period parameters rely on the TimeUnit argument to determine the format of the value, such as seconds or milliseconds.

The first two schedule() methods in the above table take a Callable or Runnable, respectively, perform the task after some delay and return a ScheduledFuture<V> instance. ScheduledFuture<V> is identical to Future<V> class, except that it includes a getDelay() method that returns the delay set when the process was created. The following uses the schedule() method with Callable and Runnable tasks :

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

Runnable task1 = () -> System.out.println("Hello Zoo");

Callable<String> task2 = () -> "Monkey";

Future<?> result1 = service.schedule(task1, 10, TimeUnit.SECONDS);

Future<?> result2 = service.schedule(task2, 8, TimeUnit.MINUTES);

The first task is scheduled 10 seconds in the future, whereas the second task is scheduled 8 minutes in the future.

Note that while these tasks are scheduled in the future, the actual execution may be delayed. For example, there may be no threads available to perform the task, at which point they will just wait in the queue. Also, if the ScheduledExecutorService is shut down by the time the scheduled task execution time is reached, they will be discarded.


Leave a Reply

Your email address will not be published. Required fields are marked *