I have a Spring schedulled tasks which calls the same private method. Do I need to sync this method? Will I have the problem if shedulled tasks runned in the same time? Or will be better to extract it to the prototype component or separate schedulled classes or something else?
public class SomeScheduled {
private final RequestDispatcher requestDispatcher;
private final ErrorRegisterRepository errorRegisterRepository;
@Scheduled(cron = "0 0/4 * * * ?")
public void runRetry4minute() {
runRetry(Duration.of(4, ChronoUnit.MINUTES), 1);
}
@Scheduled(cron = "0 0/11 * * * ?")
public void runRetry11minute() {
runRetry(Duration.of(11, ChronoUnit.MINUTES), 2);
}
@Scheduled(cron = "0 0/29 * * * ?")
public void runRetry29minute() {
runRetry(Duration.of(29, ChronoUnit.MINUTES), 3);
}
private void runRetry(TemporalAmount time, int someField) {
LocalDateTime dateTime = LocalDateTime.now().minus(time);
Page<ErrorRegister> page;
int pageNum = 0;
do {
page = errorRegisterRepository.findBySomeCriteriaAndUpdatedAtBefore(someField, dateTime, PageRequest.of(pageNum, 500)); // Spring Data Jpa
page.get().forEach(errorRegister ->
requestDispatcher.dispatch(errorRegister); // inside put to ThreadPoolTaskExecutor
pageNum ;
} while (page.hasNext());
}
CodePudding user response:
The default ThreadPoolTaskScheduler
used by the @Scheduled
annotation is, according to the documentation, created with a single thread in the pool.
Assuming that you have not customised that thread pool then it's not possible for your runRetry
method to be called by multiple threads at the same time.
If your runRetry
method is not thread safe then you should guard it anyway rather than relying on current default behaviour.
CodePudding user response:
A distinct non-answer: maybe?!
Will I have the problem if shedulled tasks runned in the same time?
The internet can't tell you your requirements. It is your business logic, you have to understand A) what it is doing and B) what the consequences are when you code runs in parallel (or in sequence).
Meaning: nobody here knows what errorRegisterRepository
is actually doing.
In other words: you have to step back. You have understand what the purpose of that scheduled method is, and what difference it makes in which ways it is invoked.
Where one key element is - do you want this to block? When your method is scheduled slowly "enough", it just won't execute in parallel. But what if processing takes sometimes more time?! Then making in synchronized means: that you are potentially queuing up requests. Because another scheduled run comes in, but is blocked because a previous one is still running. If that happens repeatedly, you might run out of available threads at some point ...
Long story short: the essence of your question is that you do not understand your requirements. That is something only you can change.