Как предотвратить перекрывающиеся графики в Spring?

@Scheduled(fixedDelay = 5000)
public void myJob() {
     Thread.sleep(12000);
}

Как я могу предотвратить выполнение этого задания spring, если предыдущая процедура еще не завершена?

Ответы

Ответ 1

С fixedDelay период измеряется после завершения задания, поэтому не беспокойтесь.

Ответ 2

по умолчанию, spring использует однопоточный Executor. поэтому никакие две задачи @Scheduled никогда не будут перекрываться. даже два метода @Scheduled в совершенно несвязанных классах не будут перекрываться просто потому, что существует только один поток для выполнения всех задач @Scheduled.

Кроме того, даже если вы замените исполняемого по умолчанию Исполнителя на исполнитель на основе пула потоков, эти Исполнители обычно задерживают выполнение экземпляра задачи до завершения ранее запланированного экземпляра. это верно для графиков fixedDelay, fixedInterval и cron. например, эта конфигурация spring создаст ScheduledThreadPoolExecutor, которая использует threadpool, но не разрешает одновременные экземпляры одного и того же расписания так же, как вы этого хотите:

@Configuration
@EnableScheduling
...
public class MySpringJavaConfig {
    @Bean(destroyMethod = "shutdown")
    public Executor taskScheduler() {
        return Executors.newScheduledThreadPool(5);
    }
    ...
}

вот javadoc для ScheduledThreadPoolExecutor:: scheduleAtFixedRate, который указывает:

Если какое-либо выполнение этой задачи занимает больше времени, чем ее период, последующие исполнения могут задерживаться, но не будут выполняться одновременно.

note: эта функция недействительна для задач @Async. spring создаст столько одновременных экземпляров тех, которые необходимы (если в пуле есть достаточные потоки).