ScheduledExecutorService

ScheduledExecutorService is an interface which is an extension of ExecutorService in Java’s java.util.concurrent package that adds support for delayed and periodic task execution. It is particularly useful for scheduling tasks to run after a certain delay, or to execute tasks periodically at a fixed rate or with a fixed delay between executions.

The core objective of ScheduledExecutorService is to allow developers to:

  • Schedule tasks for one-time execution after a delay.
  • Schedule tasks to repeat at a fixed rate or with a fixed delay.
  • Manage concurrent execution of scheduled tasks using a thread pool.

This is particularly useful in applications that require precise timing control, such as periodic maintenance jobs, monitoring systems, automatic backups, and timeout handling.

Characteristics

  1. Thread Pool Based:
    It uses a pool of threads rather than a single thread (unlike Timer), improving performance and fault tolerance.

  2. Accurate Scheduling:
    Task execution can be finely controlled using TimeUnit to express delays and periods.

  3. Robustness:
    If a task throws an exception, it does not prevent future tasks from executing—unlike Timer, which terminates the entire timer thread on one exception.

  4. Flexible Task Types:
    It accepts both Runnable (does not return result) and Callable (returns a result) tasks.

  5. Result Handling:
    Scheduled tasks return a ScheduledFuture, allowing developers to retrieve results or cancel tasks if needed.

Scheduling Types

ScheduledExecutorService supports three main scheduling types:

  1. Delayed Execution:

  • A task is executed once after a specified delay.
  • Useful for postponing the start of a task (e.g., delaying initialization).
  1. Fixed-Rate Scheduling:
  • A task is executed at consistent intervals, irrespective of its execution duration.
  • The next execution time is calculated based on the initial scheduled time, not the task’s end.
  • Suitable for tasks that must run regularly (e.g., periodic updates).
  1. Fixed-Delay Scheduling:
  • A task is executed repeatedly, with a fixed delay between the end of one execution and the start of the next.
  • Suitable for tasks that should rest between executions (e.g., background maintenance).

Advantages Over Timer

Feature Timer ScheduledExecutorService
Threads Single-threaded Thread pool-based
Exception Handling Stops on unchecked exception Isolates task failures
Flexibility Basic High (custom policies, delay control)
Result Handling None Returns ScheduledFuture
Scalability Limited Scalable and concurrent

ScheduledExecutorService Methods

1. Task Scheduling Methods

Method Description
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) Schedules a one-time task to execute after a specified delay.
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) Schedules a Callable to execute after a delay and return a result.
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) Schedules a task to run periodically at a fixed rate, beginning after an initial delay.
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) Schedules a task to run with a fixed delay between the end of one execution and the start of the next.
 
Fixed Rate = Executes tasks at regular intervals regardless of duration.

Fixed Delay = Waits for task completion, then delays before next run.

2. Inherited from ExecutorService

These are also available from its parent interface ExecutorService:

Method Description
<T> Future<T> submit(Callable<T> task) Submits a Callable for execution and returns a Future.
<T> Future<T> submit(Runnable task, T result) Submits a Runnable task and returns a Future that returns the given result.
Future<?> submit(Runnable task) Submits a Runnable and returns a Future representing task completion.
void shutdown() Initiates an orderly shutdown of the executor.
List<Runnable> shutdownNow() Forces shutdown and attempts to cancel actively executing tasks.
boolean isShutdown() Checks if shutdown has been initiated.
boolean isTerminated() Checks if all tasks have completed post-shutdown.
boolean awaitTermination(long timeout, TimeUnit unit) Blocks until shutdown is complete or timeout occurs.
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) Executes all tasks and waits for them to complete.
<T> T invokeAny(Collection<? extends Callable<T>> tasks) Executes all tasks and returns the result of one that completes successfully first.

Program

An example that demonstrates the use of ScheduledExecutorService to schedule tasks for execution after a delay and periodically:

import java.util.concurrent.*;
public class ScheduledExecutorServiceDemo {
    public static void main(String[] args) {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        // Task 1: Run after a delay of 2 seconds
        executor.schedule(() -> {
            System.out.println("Task 1 executed after 2 seconds.");
        }, 2, TimeUnit.SECONDS);
        // Task 2: Run after a delay of 5 seconds, and then every 3 seconds
        executor.scheduleAtFixedRate(() -> {
            System.out.println("Task 2 executed at fixed rate.");
        }, 5, 3, TimeUnit.SECONDS);
        // Task 3: Run after an initial delay of 1 second, then with a delay of 4 seconds after each execution
        executor.scheduleWithFixedDelay(() -> {
            System.out.println("Task 3 executed with fixed delay.");
        }, 1, 4, TimeUnit.SECONDS);
        // Shutdown the executor after 20 seconds
        executor.schedule(() -> {
            executor.shutdown();
        }, 20, TimeUnit.SECONDS);
    }
}

/*
C:\>javac ScheduledExecutorServiceDemo.java

C:\>java ScheduledExecutorServiceDemo
Task 3 executed with fixed delay.
Task 1 executed after 2 seconds.
Task 2 executed at fixed rate.
Task 3 executed with fixed delay.
Task 2 executed at fixed rate.
Task 3 executed with fixed delay.
Task 2 executed at fixed rate.
Task 3 executed with fixed delay.
Task 2 executed at fixed rate.
Task 2 executed at fixed rate.
Task 3 executed with fixed delay.
Task 2 executed at fixed rate.

*/

Explanation of above program,

  1. Executor Creation: newScheduledThreadPool(1) creates a ScheduledExecutorService with a thread pool of size 1.
  2. Task Scheduling:
  • Task 1: schedule(…) schedules a task to run after a delay of 2 seconds.
  • Task 2: scheduleAtFixedRate(…) schedules a task to run after an initial delay of 5 seconds, and then every 3 seconds thereafter.
  • Task 3: scheduleWithFixedDelay(…) schedules a task to run after an initial delay of 1 second, and then with a fixed delay of 4 seconds between the termination of one execution and the commencement of the next.
  1. Shutdown: The executor is scheduled to be shut down after 20 seconds using another schedule(…) This initiates an orderly shutdown, allowing previously submitted tasks to complete.
  2. Execution: Each task prints a message indicating its execution.

Practical Applications

  • System Monitoring: Repeatedly check server or resource status.
  • Periodic Data Sync: Sync data to a database or cloud every few minutes.
  • Timeout Implementation: Delay task execution to act as a timeout handler.
  • Email Reminders: Schedule reminders at future times.
  • Cleanup Jobs: Run cleanup logic after certain intervals or on shutdown.

ScheduledExecutorService is a powerful and flexible tool for scheduling tasks in Java applications. It is highly recommended over Timer for any task that requires delay, repetition, concurrency, or robustness. By combining accurate timing, exception isolation, and thread pool management, it provides an ideal foundation for building reliable, scheduled task execution in modern, multithreaded applications.

Scroll to Top