Reputation: 2385
If i want a method to repeat async, can i use @Scheduled and @Async together ?
@Async
@Scheduled(fixedDelay = x)
public void doSomethingEveryXMinuteAsync() {
// action
}
or is there another standard way to achive this ?
Upvotes: 8
Views: 19797
Reputation: 1211
You may also set the property:
spring.task.scheduling.pool.size
Upvotes: 1
Reputation: 1
@Async
and @Scheduled
method shouldn't be in a same class.Upvotes: 0
Reputation: 2018
You should configure implementing SchedulingConfigurer
:
@Configuration
@EnableScheduling
public class ScheduledConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar)
{
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(10);
threadPoolTaskScheduler.setThreadNamePrefix("your-scheduler-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}
With this code you achieve parallel execution of your method which is annotated with @Scheduled
.
Upvotes: 2
Reputation: 512
Implement SchedulingConfigurer and override configureTasks method. Define poolsize more than one, It will work as you are expecting.
Upvotes: 2
Reputation: 265
There is no need to use @Async. Just use fixedRate attribute of @Scheduled instead of fixedDelay. Spring will make another invocation on the method after the given time regardless of any call is already being processed.
UPDATE:
Apparently fixedRate attribute does not enforce a scheduled method to be called asynchronously and increasing pool size of scheduler task executor only enables asynchronous execution of independent @Scheduled methods. Even putting @Async on the method does not make it work as OP has asked.
ScheduledAnnotationBeanPostProcessor just creates a Runnable from the @Scheduled method and does not create any pointcut as @Async method processor would. ScheduledThreadPoolExecutor waits until Runnable#run() is finished and sets the next execution time using the start time and the fixed rate. So if the method call takes more time than the scheduled time, the next task is triggered right after the previous call is finished.
An easy solution would be extracting the actual method into another class as a @Async method and calling this method from the @Scheduled method.
Upvotes: 10