I have multiple components with @Scheduled
annotations, and I see that Spring only starts one at a time, even if they are scheduled to run on the same time.
My use case is as follows. I want each @Scheduled annotation to run in its own thread, but only once for each thread.
Given this pseudo code with two schedulers:
@Scheduled(cron = "0 * * * * *") //run every minute
public void methodA() {
log.info("Running method A");
executeLongRunningJob("Finished method A");
}
@Scheduled(cron = "0 * * * * *") //run every minute
public void methodB() {
log.info("Running method B");
executeLongRunningJob("Finished method B");
}
private void executeLongRunningJob(String msg) {
Thread.sleep(70 seconds);
System.out.println(msg);
}
Note that the task takes longer time than the scheduler is scheduled to run. This is crucial. I don't want the scheduler to start again before its finished running.
Running this code out of the box gives me this output:
Running method A
Finished method A
Running method B
Finished method B
Running method A
Finished method A
Running method B
Finished method B
... and so on
So obviously its running both schedulers in a single thread.
When I put @Async
on my expensive method, then I almost get the correct behavior, except the expensive method is not finished before a new scheduler is started.
Running method A
Running method B
Running method A
Running method B
Finished method A
Finished method B
... and so on
What I would like is this output:
Running method A
Running method B
Finished method A
Finished method B
Running method A
Running method B
Finished method A
Finished method B
... and so on
How can I accomplish this? I want each Scheduler to run concurrently, but wait until it is finished before allowed to run again. Remember I have more than two Schedulers running in same and sometimes different times.
You're right - by default scheduler uses a thread pool with size 1, so every task is being processed sequentially. You can it by configuring
TaskScheduler
bean with desired pool size. Consider following example:It will run every scheduled task in a separate thread, for example: