Подтвердить что ты не робот

Используются ли spring @Scheduled аннотированные методы для разных потоков?

У меня есть несколько методов с аннотацией @Scheduled(fixedDelay=10000).

В контексте приложения у меня есть эта настройка на основе аннотаций:

<task:annotation-driven />

Проблема в том, что иногда выполнение некоторых методов задерживается на секунды и даже минуты.

Я предполагаю, что даже если метод занимает некоторое время, чтобы завершить выполнение, другие методы все равно будут выполняться. Так что я не понимаю задержки.

Есть ли способ уменьшить или даже убрать задержку?

4b9b3361

Ответ 1

Документация о расписании гласит:

Если вы не укажете атрибут размера пула, пул потоков по умолчанию будет иметь только один поток.

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

Ответ 2

Для полноты кода ниже показан самый простой способ настройки планировщика с помощью java config:

@Configuration
@EnableScheduling
public class SpringConfiguration {

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

Когда требуется больше управления, класс @Configuration может реализовать SchedulingConfigurer.

Ответ 3

Метод, аннотированный с помощью @Scheduled, предназначен для запуска отдельно, в другом потоке в момент времени.

Если вы не указали TaskScheduler в своей конфигурации, Spring будет использовать

Executors.newSingleThreadScheduledExecutor();

который возвращает ScheduledExecutorService, который выполняется в одном потоке. Таким образом, если у вас несколько методов @Scheduled, хотя они и запланированы, каждый из них должен дождаться завершения потока для выполнения предыдущей задачи. Вы можете продолжать получать большие и большие задержки, так как очередь заполняется быстрее, чем она освобождается.

Убедитесь, что вы настроили среду планирования с соответствующим количеством потоков.

Ответ 4

вы можете использовать:

@Bean()
public  ThreadPoolTaskScheduler  taskScheduler(){
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(2);
    return  taskScheduler;
}

Ответ 5

Аннотация @EnableScheduling предоставляет ключевую информацию и способы ее решения:

По умолчанию будет выполняться поиск соответствующего определения планировщика: либо уникальный компонент TaskScheduler в контексте, либо TaskScheduler бин с именем "taskScheduler" в противном случае; такой же поиск тоже будет выполняется для bean-компонента ScheduledExecutorService. Если ни один из двух разрешима, локальный однопоточный планировщик по умолчанию будет Создано и использовано внутри регистратора.

Когда требуется больше контроля, класс @Configuration может реализовать SchedulingConfigurer. Это позволяет получить доступ к основному Экземпляр ScheduledTaskRegistrar. Например, следующий пример демонстрирует, как настроить исполнителя, используемого для выполнения запланированного Задачи:

 @Configuration
 @EnableScheduling
 public class AppConfig implements SchedulingConfigurer {

     @Override
     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
         taskRegistrar.setScheduler(taskExecutor());
     }

     @Bean(destroyMethod="shutdown")
     public Executor taskExecutor() {
         return Executors.newScheduledThreadPool(100);
     }
 }

(акцент добавлен)

Ответ 6

пружина по умолчанию, использующая одну нить для задания расписания. Вы можете использовать @Configuration для реализации классов SchedulingConfigurer. ссылка: https://crmepham.github.io/spring-boot-multi-thread-scheduling/