Java – how do you configure spring to perform overlapping fixedrate tasks?
I'm trying to execute tasks at a fixed rate using the @ scheduled annotation in Java spring However, by default, if the task is slower than the rate, spring will not execute the fixedrate task at a fixed rate Are there any settings I can add to my spring configuration to change this behavior?
Example:
@Service public class MyTask{ @Scheduled(fixedRate = 1000) public void doIt(){ // this sometimes takes >1000ms,in which case the next execution is late ... } }
I have a solution, but it doesn't seem ideal Basically, I just replace the default single thread executor with a thread pool, and then I have a scheduling method to call asynchronous methods, because the @ async annotation allows concurrent execution:
@Service public class MyTask{ @Async public void doIt(){ // this sometimes takes >1000ms,but the next execution is on time ... } } @Service public class MyTaskScheduler{ ... @Scheduled(fixedRate = 1000) public void doIt(){ myTask.doIt(); } } @Configuration @EnableScheduling @EnableAsync public class MySpringJavaConfig{ @Bean(destroyMethod = "shutdown") public Executor taskScheduler() { return Executors.newScheduledThreadPool(5); } }
Boring details of my real scene: in my production code, my task takes 10 milliseconds to 10 minutes, depending on the current workload Ideally, I want to capture a new thread from the pool every 1000 milliseconds so that the number of concurrent threads increases as the workload increases Obviously I have an upper limit (among other controls) to prevent things from getting out of control
Solution
The taskscheduler API (which supports some spring scheduling behaviors) seems to be defined as a behavior that blocks your requests
Subsequent and sequential actions seem to indicate that the next execution will only occur after the current execution is completed
More importantly, scheduledexecutorservice #scheduleatfixedrate (..) (used by the built-in taskscheduler Implementation)
Therefore, another layer of implementation can prevent the behavior you want
I don't recommend a possible solution, because the API doesn't seem to be built around it. It defines and provides its own task scheduler, which runs tasks at the same time Check @ enableshcheduling and schedulingconfigurator to learn how to register the taskscheduler