Mastering Spring Boot 3 Scheduled Tasks: Thread Pools, Concurrency & Customization

This article explains how to use Spring's @Scheduled annotation for timed tasks, demonstrates concurrency issues when multiple tasks share a single thread, and shows how to configure default and custom thread pools in Spring Boot 3 to ensure reliable execution.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring Boot 3 Scheduled Tasks: Thread Pools, Concurrency & Customization

1. Introduction

In Spring, scheduled tasks allow developers to execute specific operations at fixed times or intervals, such as automatic updates, data cleanup, or notifications.

The most common way is using the @Scheduled annotation, which can be placed on a method to define its execution schedule.

2. Using @Scheduled and Cron Expressions

The @Scheduled annotation supports fixed‑rate, fixed‑delay, and Cron expressions. Example using Cron to run every 5 seconds:

public class SchedulingService {
    // Every 5 seconds
    @Scheduled(cron = "0/5 * * * * ?")
    public void s() {
        System.out.printf("%s - 执行任务 task-1: %s%n",
            Thread.currentThread().getName(),
            new SimpleDateFormat("HH:mm:ss").format(new Date()));
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { }
    }
}

Output shows the task runs as expected.

2.1 Multiple Tasks Concurrency Issue

Adding another task that runs every 2 seconds:

// Another scheduled task
@Scheduled(cron = "0/2 * * * * ?")
public void s2() {
    System.out.printf("%s - 执行任务 task-2: %s%n",
        Thread.currentThread().getName(),
        new SimpleDateFormat("HH:mm:ss").format(new Date()));
    try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { }
}

Running both tasks reveals they share the same thread, causing unexpected behavior; you need to separate execution times or configure a thread pool.

2.2 Default Thread Pool

Spring registers a TaskScheduler or ScheduledExecutorService during container startup. If none is defined, it creates a single‑core thread pool with Integer.MAX_VALUE queue capacity.

2.3 Custom Thread Pool

You can provide your own TaskScheduler or ScheduledExecutorService bean, e.g.:

@Bean
public TaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.setPoolSize(2);
    scheduler.initialize();
    return scheduler;
}

Or configure the scheduler attribute on @Scheduled (available since Spring 6.1):

@Scheduled(cron = "0/5 * * * * ?", scheduler = "task1")

2.4 ThreadPoolTaskScheduler in Spring Boot

Spring Boot auto‑configures a ThreadPoolTaskScheduler bean. Its core pool size defaults to 1 (property spring.task.scheduling.pool.size).

@ConfigurationProperties("spring.task.scheduling")
public class TaskSchedulingProperties {
    private final Pool pool = new Pool();
    public static class Pool {
        private int size = 1;
    }
}

Therefore, when multiple scheduled tasks exist, you should increase the pool size via configuration or a custom bean to avoid contention.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

concurrencythread poolScheduled Tasks
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.