DEV Community

Munaf Badarpura
Munaf Badarpura

Posted on

Spring Boot @Scheduled Tutorial: Building Scheduled Tasks with TaskScheduler

Task scheduling is the process of executing methods or tasks at specified times or intervals, either once or repeatedly, without manual intervention. Spring Boot simplifies this with the @Scheduled annotation and the TaskScheduler.

This enabling developers to automate tasks like logging, notifications, and data processing. This blog explores how to implement scheduled tasks in Spring Boot, including configuration, use cases, and best practices.

What is Task Scheduling in Spring Boot?

Spring Boot provides built-in support for scheduling through the @Scheduled annotation, which integrates with the TaskScheduler interface. By default, it uses a ScheduledExecutorService under the hood, leveraging a thread pool for task execution. This allows for efficient management of recurring or delayed tasks without manual thread handling.

Common Use Cases

  • Logging user activity in a separate thread.
  • Sending emails or SMS notifications asynchronously after user actions.
  • Processing multiple image uploads, database queries, or API calls in parallel.
  • Cleaning up expired database records.
  • Archiving logs.
  • Fetching data from external APIs regularly.
  • Performing regular health checks on external systems or services.

Setting Up Scheduled Tasks

Steps to Implement

  1. Enable Scheduling: Add @EnableScheduling to the main application class to activate Spring’s scheduling support.
  2. Annotate the Method: Use @Scheduled on the method you want to schedule.
  3. Method Requirements: The method must be void and take no arguments.

Example Configuration

import org.springframework.boot.SpringApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@Component
class ScheduledTasks {
    @Scheduled(fixedRate = 5000) // Runs every 5 seconds
    public void reportCurrentTime() {
        System.out.println("Current time: " + new java.util.Date());
    }
}

Enter fullscreen mode Exit fullscreen mode

How @Scheduled Works

When a method is annotated with @Scheduled, Spring:

  1. Registers it as a scheduled task.
  2. Delegates execution to a TaskScheduler implementation.
  3. Uses a thread pool (defaulting to ScheduledExecutorService) for concurrent task execution.
  4. By default, employs a single-threaded executor, running tasks sequentially.

Customizing for Concurrency

By default, tasks run sequentially. To enable parallel execution, configure a custom TaskScheduler with a thread pool:

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
public class TaskSchedulingConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5); // Allows 5 tasks to run concurrently
        scheduler.setThreadNamePrefix("CustomTaskScheduler-"); // Optional: Custom thread name
        scheduler.initialize(); // Initialize the scheduler
        return scheduler;
    }
}

Enter fullscreen mode Exit fullscreen mode

Asynchronous Task Scheduling

Blocking Behavior

By default, @Scheduled tasks are blocking. For example, if a task takes 5 seconds and is scheduled every 2 seconds, it will only rerun after the previous execution completes. This can lead to delays.

Enabling Async Execution

To avoid blocking, use the @Async annotation:

  1. Add @EnableAsync to the main application class.
  2. Annotate the scheduled method with @Async.

Example:

import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@EnableAsync
@Component
class ScheduledTasks {
    @Scheduled(fixedRate = 2000) // Every 2 seconds
    @Async
    public void asyncTask() {
        try {
            Thread.sleep(5000); // Simulates a 5-second task
            System.out.println("Async task completed at: " + new java.util.Date());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Note: @Async is ignored if the method is called within the same class due to Spring’s proxy mechanism. Move the method to a separate class or use a proxy instance.

Benefits of @async

  • Frees the main thread for other operations by offloading time-consuming tasks to a new thread.
  • Improves responsiveness in applications with heavy scheduled workloads.

Read complete blog here : https://www.codingshuttle.com/blogs/spring-boot-scheduled-tutorial-building-scheduled-tasks-with-task-scheduler/

Top comments (0)