ScheduledExecutorService in Java

Introduction

The ScheduledExecutorService is an interface in Java that is part of the java.util.concurrent package. It extends ExecutorService and provides methods for scheduling tasks to run after a delay or periodically. This is particularly useful for tasks that need to be executed at regular intervals or after a certain delay.

Table of Contents

  1. Overview of ScheduledExecutorService
  2. Creating a ScheduledExecutorService
  3. Scheduling a Task with schedule()
  4. Scheduling a Periodic Task with scheduleAtFixedRate()
  5. Scheduling a Periodic Task with scheduleWithFixedDelay()
  6. Example: Using ScheduledExecutorService
  7. Shutting Down ScheduledExecutorService
  8. Conclusion

1. Overview of ScheduledExecutorService

The ScheduledExecutorService interface provides methods to schedule commands to run after a given delay or to execute periodically. Some of the key methods include:

  • schedule(Runnable command, long delay, TimeUnit unit): Schedules a command to run after a delay.
  • schedule(Callable<V> callable, long delay, TimeUnit unit): Schedules a callable task to run after a delay.
  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit): Schedules a command to run periodically with a fixed rate.
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit): Schedules a command to run periodically with a fixed delay between the end of one execution and the start of the next.

2. Creating a ScheduledExecutorService

You can create a ScheduledExecutorService using the Executors factory methods, such as newScheduledThreadPool.

Example:

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;

public class ScheduledExecutorServiceExample {
    public static void main(String[] args) {
        // Creating a ScheduledExecutorService with a pool of 2 threads
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

        // Your tasks go here

        scheduledExecutorService.shutdown();
    }
}

3. Scheduling a Task with schedule()

The schedule method can be used to schedule a task to run after a specified delay.

Example:

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ScheduledTaskExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

        // Schedule a task to run after a 5-second delay
        scheduledExecutorService.schedule(() -> {
            System.out.println("Task executed after 5 seconds");
        }, 5, TimeUnit.SECONDS);

        scheduledExecutorService.shutdown();
    }
}

Output:

Task executed after 5 seconds

4. Scheduling a Periodic Task with scheduleAtFixedRate()

The scheduleAtFixedRate method can be used to schedule a task to run periodically with a fixed rate.

Example:

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class FixedRateTaskExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

        // Schedule a task to run every 3 seconds, with an initial delay of 2 seconds
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            System.out.println("Fixed rate task executed at " + System.currentTimeMillis());
        }, 2, 3, TimeUnit.SECONDS);

        // Let the main thread sleep for 10 seconds to observe the scheduled task execution
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        scheduledExecutorService.shutdown();
    }
}

Output:

Fixed rate task executed at [time]
Fixed rate task executed at [time + 3 seconds]
Fixed rate task executed at [time + 6 seconds]
Fixed rate task executed at [time + 9 seconds]

5. Scheduling a Periodic Task with scheduleWithFixedDelay()

The scheduleWithFixedDelay method can be used to schedule a task to run periodically with a fixed delay between the end of one execution and the start of the next.

Example:

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class FixedDelayTaskExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

        // Schedule a task to run with a fixed delay of 3 seconds between the end of one execution and the start of the next
        scheduledExecutorService.scheduleWithFixedDelay(() -> {
            System.out.println("Fixed delay task executed at " + System.currentTimeMillis());
        }, 2, 3, TimeUnit.SECONDS);

        // Let the main thread sleep for 10 seconds to observe the scheduled task execution
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        scheduledExecutorService.shutdown();
    }
}

Output:

Fixed delay task executed at [time]
Fixed delay task executed at [time + execution time + 3 seconds]
Fixed delay task executed at [time + 2 * (execution time + 3 seconds)]
Fixed delay task executed at [time + 3 * (execution time + 3 seconds)]

6. Example: Using ScheduledExecutorService

Let's create a complete example that demonstrates how to create a ScheduledExecutorService, schedule tasks, and shut it down.

Example:

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class ScheduledTask implements Runnable {
    private final String name;

    public ScheduledTask(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("Task " + name + " is being executed by " + Thread.currentThread().getName() + " at " + System.currentTimeMillis());
    }
}

public class ScheduledExecutorServiceDemo {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

        // Schedule a task to run after a 5-second delay
        scheduledExecutorService.schedule(new ScheduledTask("One-Time Task"), 5, TimeUnit.SECONDS);

        // Schedule a task to run every 3 seconds, with an initial delay of 2 seconds
        scheduledExecutorService.scheduleAtFixedRate(new ScheduledTask("Fixed-Rate Task"), 2, 3, TimeUnit.SECONDS);

        // Schedule a task to run with a fixed delay of 3 seconds between the end of one execution and the start of the next
        scheduledExecutorService.scheduleWithFixedDelay(new ScheduledTask("Fixed-Delay Task"), 2, 3, TimeUnit.SECONDS);

        // Let the main thread sleep for 10 seconds to observe the scheduled task execution
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        scheduledExecutorService.shutdown();

        try {
            if (!scheduledExecutorService.awaitTermination(60, TimeUnit.SECONDS)) {
                scheduledExecutorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduledExecutorService.shutdownNow();
        }

        System.out.println("All tasks are finished.");
    }
}

Output:

Task One-Time Task is being executed by pool-1-thread-1 at [time]
Task Fixed-Rate Task is being executed by pool-1-thread-2 at [time + 2 seconds]
Task Fixed-Delay Task is being executed by pool-1-thread-1 at [time + 2 seconds]
Task Fixed-Rate Task is being executed by pool-1-thread-2 at [time + 5 seconds]
Task Fixed-Delay Task is being executed by pool-1-thread-1 at [time + 2 seconds + execution time + 3 seconds]
Task Fixed-Rate Task is being executed by pool-1-thread-2 at [time + 8 seconds]
Task Fixed-Delay Task is being executed by pool-1-thread-1 at [time + 2 * (execution time + 3 seconds)]
All tasks are finished.

7. Shutting Down ScheduledExecutorService

It's important to properly shut down the ScheduledExecutorService to release resources. You can shut it down gracefully or forcefully.

Graceful Shutdown:

scheduledExecutorService.shutdown();
try {
    if (!scheduledExecutorService.awaitTermination(60, TimeUnit.SECONDS)) {
        scheduledExecutorService.shutdownNow();
    }
} catch (InterruptedException e) {
    scheduledExecutorService.shutdownNow();
}

Forceful Shutdown:

scheduledExecutorService.shutdownNow();

8. Conclusion

The ScheduledExecutorService interface in Java provides a powerful framework for scheduling tasks to run after a delay or periodically. By using ScheduledExecutorService, you can efficiently manage and execute scheduled tasks in your applications. This tutorial covered the basics of creating a ScheduledExecutorService, scheduling tasks, and shutting it down.

Happy coding!

Continue Learning with Java Guides

Want to take your programming skills to the next level? Explore my practical Udemy courses on Java, Spring Boot, Microservices, Full-Stack Development, Docker, and Generative AI. You can also follow my structured learning roadmaps to become a professional developer.

By Ramesh Fadatare - Udemy Instructor Partner

Comments