Anders Pedersen
Anders Pedersen

Reputation: 2385

using @Scheduled and @Async together?

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

Answers (5)

Doctor Parameter
Doctor Parameter

Reputation: 1211

You may also set the property:

spring.task.scheduling.pool.size

Upvotes: 1

gotouei
gotouei

Reputation: 1

  1. @Async and @Scheduled method shouldn't be in a same class.
  2. follow the manual and add AsyncConfigurerhttps://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableAsync.html

Upvotes: 0

Heril Muratovic
Heril Muratovic

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

Sarang
Sarang

Reputation: 512

Implement SchedulingConfigurer and override configureTasks method. Define poolsize more than one, It will work as you are expecting.

Upvotes: 2

Yuqu
Yuqu

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

Related Questions