我需要同步方法 Scheduled 方法吗?
Do I need synchronize method Scheduled method?
我有一个 Spring 调用相同私有方法的计划任务。
我需要同步这个方法吗?如果 shedulled 任务同时运行,我会遇到问题吗?或者将其提取到原型组件或单独预定 类 或其他东西会更好?
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());
}
根据 the documentation,@Scheduled
注释使用的默认 ThreadPoolTaskScheduler
是使用池中的单个线程创建的。
假设你没有自定义那个线程池那么你的runRetry
方法不可能被多个线程同时调用。
如果您的 runRetry
方法不是线程安全的,那么无论如何您都应该保护它,而不是依赖当前的默认行为。
我有一个 Spring 调用相同私有方法的计划任务。 我需要同步这个方法吗?如果 shedulled 任务同时运行,我会遇到问题吗?或者将其提取到原型组件或单独预定 类 或其他东西会更好?
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());
}
根据 the documentation,@Scheduled
注释使用的默认 ThreadPoolTaskScheduler
是使用池中的单个线程创建的。
假设你没有自定义那个线程池那么你的runRetry
方法不可能被多个线程同时调用。
如果您的 runRetry
方法不是线程安全的,那么无论如何您都应该保护它,而不是依赖当前的默认行为。