@Scheduled(fixedDelay = 5000)
public void myJob() {
Thread.sleep(12000);
}
How can I prevent this spring job from running if the previous routine is not yet finished?
We can deploy multiple Scheduler Instances using the ShedLock library which ensures only one instance to run at a time by using a locking mechanism in a shared database.
Schedule a Task at Fixed Delay In this case, the duration between the end of the last execution and the start of the next execution is fixed. The task always waits until the previous one is finished. This option should be used when it's mandatory that the previous execution is completed before running again.
Another way to stop the scheduler would be manually canceling its Future. In the cases with multiple scheduler tasks, then we can maintain the Future map inside of the custom scheduler pool but cancel the corresponding scheduled Future based on scheduler class.
The Spring Framework provides abstractions for asynchronous execution and scheduling of tasks with the TaskExecutor and TaskScheduler interfaces, respectively. Spring also features implementations of those interfaces that support thread pools or delegation to CommonJ within an application server environment.
by default, spring uses a single-threaded Executor. so no two @Scheduled tasks will ever overlap. even two @Scheduled methods in completely unrelated classes will not overlap simply because there is only a single thread to execute all @Scheduled tasks.
furthermore, even if you replace the default Executor with a thread pool based executor, those Executors will typically delay the execution of a task instance until the previously scheduled instance completes. this is true for fixedDelay, fixedInterval, and cron based schedules. for example, this spring configuration will create a ScheduledThreadPoolExecutor that uses a threadpool, but does not allow concurrent instances of the same schedule just as you desire:
@Configuration
@EnableScheduling
...
public class MySpringJavaConfig {
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5);
}
...
}
here is the javadoc for ScheduledThreadPoolExecutor::scheduleAtFixedRate which specifies:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
note: this functionality does not hold true for @Async tasks. spring will create as many concurrent instances of those as needed (if there are sufficient threads in the pool).
With fixedDelay
, the period is measured after the completion of job, so no worries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With