1. Обзор
В этой статье мы обсудим механизмы планирования задач Spring — TaskScheduler
и его готовые реализации, а также различные триггеры для использования. Если вы хотите узнать больше о планировании в Spring, ознакомьтесь со статьями @Async
и @Scheduled
.
TaskScheduler
был представлен в Spring 3.0 с множеством методов для запуска в какой-то момент в будущем. Он также возвращает объект представления интерфейса ScheduledFuture
, который можно использовать для отмены запланированной задачи или проверки ее выполнения.
Все, что нам нужно сделать, это выбрать выполняемую задачу для планирования, а затем выбрать правильную политику планирования.
2. ThreadPoolTaskScheduler
ThreadPoolTaskScheduler
хорошо подходит для управления внутренними потоками, поскольку он делегирует задачи ScheduledExecutorService
и реализует интерфейс TaskExecutor
, так что один его экземпляр может обрабатывать потенциальные асинхронные выполнения, а также аннотацию @Scheduled
.
Давайте теперь определим bean -компонент ThreadPoolTaskScheduler в
ThreadPoolTaskSchedulerConfig
: ``
@Configuration
@ComponentScan(
basePackages="com.foreach.taskscheduler",
basePackageClasses={ThreadPoolTaskSchedulerExamples.class})
public class ThreadPoolTaskSchedulerConfig {
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
ThreadPoolTaskScheduler threadPoolTaskScheduler
= new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(5);
threadPoolTaskScheduler.setThreadNamePrefix(
"ThreadPoolTaskScheduler");
return threadPoolTaskScheduler;
}
}
Настроенный bean -компонент threadPoolTaskScheduler
может выполнять задачи асинхронно на основе настроенного размера пула, равного 5.
Обратите внимание, что все имена потоков, связанные с ThreadPoolTaskScheduler
, будут иметь префикс ThreadPoolTaskScheduler
.
Давайте реализуем простую задачу, которую затем можем запланировать:
class RunnableTask implements Runnable{
private String message;
public RunnableTask(String message){
this.message = message;
}
@Override
public void run() {
System.out.println(new Date()+" Runnable Task with "+message
+" on thread "+Thread.currentThread().getName());
}
}
Теперь мы можем просто запланировать выполнение этой задачи планировщиком:
taskScheduler.schedule(
new Runnabletask("Specific time, 3 Seconds from now"),
new Date(System.currentTimeMillis + 3000)
);
TaskScheduler запланирует
эту выполняемую задачу на известную дату, ровно через 3 секунды после текущего времени.
Теперь давайте более подробно рассмотрим механизмы планирования ThreadPoolTaskScheduler .
3. Расписание запускаемой задачи с фиксированной задержкой
Планирование с фиксированной задержкой может быть выполнено с помощью двух простых механизмов:
3.1. Планирование после фиксированной задержки последнего запланированного выполнения
Давайте настроим задачу для запуска после фиксированной задержки в 1000 миллисекунд:
taskScheduler.scheduleWithFixedDelay(
new RunnableTask("Fixed 1 second Delay"), 1000);
RunnableTask всегда
будет запускаться на 1000 миллисекунд позже между завершением одного выполнения и началом следующего.
3.2. Планирование после фиксированной задержки определенной даты
Давайте настроим задачу для запуска после фиксированной задержки заданного времени запуска:
taskScheduler.scheduleWithFixedDelay(
new RunnableTask("Current Date Fixed 1 second Delay"),
new Date(),
1000);
RunnableTask будет вызываться в указанное время выполнения, которое в основном совпадает со временем запуска метода
@PostConstruct
, а затем с задержкой в 1000 миллисекунд.
4. Планирование по фиксированной ставке
Существует два простых механизма планирования выполняемых задач с фиксированной скоростью:
4.1. Планирование RunnableTask
с фиксированной скоростью
Давайте запланируем выполнение задачи с фиксированной скоростью в миллисекундах :
taskScheduler.scheduleAtFixedRate(
new RunnableTask("Fixed Rate of 2 seconds") , 2000);
Следующая RunnableTask
будет запускаться всегда через 2000 миллисекунд, независимо от состояния последнего выполнения, которое может все еще выполняться.
4.2. Планирование RunnableTask
с фиксированной скоростью от заданной даты
taskScheduler.scheduleAtFixedRate(new RunnableTask(
"Fixed Rate of 2 seconds"), new Date(), 3000);
RunnableTask запустится через 3000 миллисекунд после текущего времени .
5. Планирование с помощью CronTrigger
CronTrigger
используется для планирования задачи на основе выражения cron:
CronTrigger cronTrigger
= new CronTrigger("10 * * * * ?");
Предоставленный триггер можно использовать для запуска задачи в соответствии с определенной заданной частотой или расписанием:
taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);
В этом случае RunnableTask
будет выполняться на 10-й секунде каждой минуты.
6. Планирование с помощью PeriodicTrigger
Давайте используем PeriodicTrigger
для планирования задачи с фиксированной задержкой в 2000 миллисекунд:
PeriodicTrigger periodicTrigger
= new PeriodicTrigger(2000, TimeUnit.MICROSECONDS);
Сконфигурированный bean-компонент PeriodicTrigger
будет использоваться для запуска задачи после фиксированной задержки в 2000 миллисекунд.
Теперь давайте запланируем RunnableTask
с помощью PeriodicTrigger
:
taskScheduler.schedule(
new RunnableTask("Periodic Trigger"), periodicTrigger);
Мы также можем настроить PeriodicTrigger
для инициализации с фиксированной скоростью, а не с фиксированной задержкой, также мы можем установить начальную задержку для первой запланированной задачи на заданные миллисекунды.
Все, что нам нужно сделать, это добавить две строки кода перед оператором return в bean
- компоненте PeriodicTrigger :
periodicTrigger.setFixedRate(true);
periodicTrigger.setInitialDelay(1000);
Мы использовали метод setFixedRate
для планирования задачи с фиксированной скоростью, а не с фиксированной задержкой, затем метод setInitialDelay
используется для установки начальной задержки только для первой запускаемой задачи.
7. Заключение
В этой быстрой статье мы показали, как запланировать выполнение задачи, используя поддержку Spring для задач.
Мы рассмотрели запуск задачи с фиксированной задержкой, с фиксированной скоростью и в соответствии с указанным триггером.
И, как всегда, код доступен в виде проекта Maven на GitHub .