Java > Concurrency and Multithreading > Executors and Thread Pools > Thread Pools and Task Management
Scheduled Thread Pool Example
This snippet demonstrates how to use a `ScheduledExecutorService` to schedule tasks to run at a fixed rate or with a fixed delay.
Code Snippet
This code uses `Executors.newScheduledThreadPool(1)` to create a scheduled thread pool with a single thread. It then demonstrates three ways to schedule tasks: `scheduleAtFixedRate`, `scheduleWithFixedDelay`, and `schedule`. `scheduleAtFixedRate` executes a task repeatedly with a fixed period between the start of each execution. `scheduleWithFixedDelay` executes a task repeatedly with a fixed delay between the end of the previous execution and the start of the next execution. `schedule` executes a task once after a specified delay. The code allows the tasks to run for 20 seconds before shutting down the scheduler. The `future.cancel(true)` allows cancelling the fixed rate task.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolExample {
public static void main(String[] args) {
// Create a scheduled executor service with 1 thread
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// Schedule a task to run every 2 seconds
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(() -> {
System.out.println("Task executed at: " + System.currentTimeMillis() / 1000);
}, 0, 2, TimeUnit.SECONDS);
// Schedule a task to run after an initial delay of 5 seconds, then every 3 seconds
scheduler.scheduleWithFixedDelay(() -> {
System.out.println("Delayed task executed at: " + System.currentTimeMillis() / 1000);
}, 5, 3, TimeUnit.SECONDS);
// Schedule a task to run once after 10 seconds
scheduler.schedule(() -> {
System.out.println("One-time task executed at: " + System.currentTimeMillis() / 1000);
}, 10, TimeUnit.SECONDS);
// Allow the tasks to run for 20 seconds
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// Cancel the recurring task (optional)
future.cancel(true);
// Shut down the scheduler
scheduler.shutdown();
}
}
Concepts Behind the Snippet
The `ScheduledExecutorService` interface extends `ExecutorService` and provides methods for scheduling tasks to run periodically or after a delay. `scheduleAtFixedRate` is suitable when you want a task to run at a specific frequency, regardless of how long the previous execution took. `scheduleWithFixedDelay` is suitable when you want a task to run a certain amount of time after the previous execution has completed. `schedule` is used for one-time delayed executions.
Real-Life Use Case
Scheduled thread pools are commonly used for tasks such as sending heartbeats, running periodic backups, generating reports, and executing maintenance tasks at regular intervals. They are also useful for implementing retry mechanisms with delays.
Best Practices
Interview Tip
Understand the difference between `scheduleAtFixedRate` and `scheduleWithFixedDelay`. Be able to explain scenarios where each method is more appropriate. Also, be prepared to discuss how to handle exceptions within scheduled tasks.
When to Use Them
Use scheduled thread pools when you need to execute tasks periodically or after a delay. They are particularly useful for tasks that need to be run on a regular basis, such as sending heartbeats or generating reports.
Memory Footprint
The memory footprint of a scheduled thread pool depends on the number of threads in the pool and the number of scheduled tasks. If a large number of tasks are scheduled with short delays, the pool can consume a significant amount of memory. Carefully consider the scheduling frequency and the number of tasks to avoid memory issues.
Alternatives
Pros
Cons
FAQ
-
What happens if a task scheduled with `scheduleAtFixedRate` takes longer to execute than the specified period?
If a task scheduled with `scheduleAtFixedRate` takes longer to execute than the period, subsequent executions may start late, but they will not overlap. The scheduler will ensure that the task is not executed concurrently. -
How do I cancel a scheduled task?
You can cancel a scheduled task by calling the `cancel()` method on the `ScheduledFuture` object returned by the scheduling method. The `cancel()` method takes a boolean argument indicating whether to interrupt the task if it is currently running. If the task has not yet started, the `cancel()` method will prevent it from running. -
Can I change the schedule of a task after it has been scheduled?
No, you cannot directly change the schedule of a task after it has been scheduled. You would need to cancel the existing task and schedule a new task with the desired schedule.