ScheduledExecutorService in Java

📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.

🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.

▶️ Subscribe to My YouTube Channel (176K+ subscribers): Java Guides on YouTube

▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube

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!

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare