Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent overlapping schedules in Spring?

@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?

like image 999
membersound Avatar asked Jun 04 '14 09:06

membersound


People also ask

Can we have multiple scheduler in spring boot?

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.

What is fixed delay in spring scheduler?

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.

How do I stop a scheduled spring job?

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.

What is spring scheduler?

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.


2 Answers

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).

like image 121
james turner Avatar answered Oct 05 '22 11:10

james turner


With fixedDelay, the period is measured after the completion of job, so no worries.

like image 21
Jose Luis Martin Avatar answered Oct 05 '22 12:10

Jose Luis Martin