Java Spring: как запустить два разных cronjobs одновременно? - PullRequest
0 голосов
/ 19 октября 2018

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

Допустим, у меня есть две разные работы cron, подобные этой:

@Scheduled(cron = "0 30 * * * *")
private void sleepForDays() {
    while(true) sleep();
}

@Scheduled(cron= "0 * * * * *")
private void logHello() {
   log("hello!");
}

У меня есть функция, которая работает в течение нескольких дней, которая активируется каждые 30 минут.(0 30 * * * *) Давайте назовем это sleepForDays().

У меня есть другая функция, которая должна записывать привет каждую минуту.Давайте назовем это logHello().

Вопросы:

  1. Как только sleepForDays() запущен, я думаю, что второй sleepForDays() не запуститсяпока первый не закончен.Правильно?

  2. После запуска sleepForDays() logHello() не работает каждую минуту.Я делаю логирование внутри этой функции в своей производственной среде, и я не вижу эти журналы в выходном файле.Ясно, что он не работает, пока sleepForDays() выполняется.

Намерения:

  1. Я хочу, чтобы разные cronJobs работалинезависимо друг от друга.Другими словами, я не хочу, чтобы sleepForDays() блокировал logHello().

  2. Я также хочу избежать повторного выполнения одного и того же cronJob.Если sleepForDays() уже выполняется, я не хочу, чтобы запускалась секунда sleepForDays().

Мой основной вопрос при публикации этого вопроса - Вопрос № 2.Что касается похожих постов в StackOverflow, я считаю, что ответ на вопрос №1 - да.Я хотел убедиться, что мои предположения в вопросе № 1 верны.

Спасибо за ваше время!

Редактировать:

Возможно, проблемао том, что я инициализирую бин TaskScheduler параметрами по умолчанию.По умолчанию TaskScheduler не поддерживают многопоточность для запланированных cronjobs.Если я инициализирую компонент TaskScheduled с поддержкой многопоточности, будет ли ответ на мой вопрос №1 все еще положительным?

Инициализация компонента будет выглядеть следующим образом:

@Bean
public static TaskScheduler taskScheduler() {
    return new ConcurrentTaskScheduler();
}

Изменить 2: Решение

Большое спасибо авторам, мне удалось запустить эти функции одновременно, используя инициализацию bean ниже.Я просто заменил TaskScheduler bean на этот:

@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(2);
    threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler"); // i dont know what it does, i used it anyways lol
    return threadPoolTaskScheduler;
}

1 Ответ

0 голосов
/ 19 октября 2018

Все методы @Scheduled по умолчанию используют один поток.Вы можете изменить это поведение, определив, например, пользовательский ThreadPoolTaskScheduler bean:

@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(5);
    threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
    return threadPoolTaskScheduler;
}
...