A method annotated with @Scheduled is meant to be run separately, on a different thread at a moment in time.
If you haven't provided a TaskScheduler in your configuration, Spring will use
Executors.newSingleThreadScheduledExecutor();
which returns an ScheduledExecutorService that runs on a single thread. As such, if you have multiple @Scheduled methods, although they are scheduled, they each need to wait for the thread to complete executing the previous task. You might keep getting bigger and bigger delays as the the queue fills up faster than it empties out.
Make sure you configure your scheduling environment with an appropriate amount of threads.
If you do not provide a pool-size attribute, the default thread pool will only have a single thread.
So if you have many scheduled tasks, you should configure the scheduler, as explained in the documentation, to have a pool with more threads, to make sure one long task doesn't delay all the other ones.
default spring using a single thread for schedule task. you can using @Configuration for class implements SchedulingConfigurer . referce: https://crmepham.github.io/spring-boot-multi-thread-scheduling/
The @EnableScheduling annotation provides the key information and how to resolve it:
By default, will be searching for an associated scheduler definition:
either a unique TaskScheduler bean in the context, or a TaskScheduler
bean named "taskScheduler" otherwise; the same lookup will also be
performed for a ScheduledExecutorService bean. If neither of the two
is resolvable, a local single-threaded default scheduler will be
created and used within the registrar.
When more control is desired, a @Configuration class may implement
SchedulingConfigurer. This allows access to the underlying
ScheduledTaskRegistrar instance. For example, the following example
demonstrates how to customize the Executor used to execute scheduled
tasks:
@Configuration
@EnableScheduling
public class AppConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
}