какая разница между фиксированной ставкой и фиксированной задержкой в расписании весны?
Я выполняю запланированные задачи с использованием Spring, и у меня есть 2 типа времени конфигурации, которое запланировано снова из последних. Что отличает 2 типа этой конфигурации.
@Scheduled(fixedDelay = 5000)
public void doJobDelay() {
// do anything
}
@Scheduled(fixedRate = 5000)
public void doJobRate() {
// do anything
}
Ответы
Ответ 1
- fixedRate: позволяет Spring запускать задание на периодические интервалы, даже если последний вызов еще может выполняться.
- fixedDelay: специально контролирует следующее время выполнения при завершении последнего выполнения.
В коде:
@Scheduled(fixedDelay=5000)
public void updateEmployeeInventory(){
System.out.println("employee inventory will be updated once only the last updated finished ");
/**
* add your scheduled job logic here
*/
}
@Scheduled(fixedRate=5000)
public void updateEmployeeInventory(){
System.out.println("employee inventory will be updated every 5 seconds from prior updated has stared, regardless it is finished or not");
/**
* add your scheduled job logic here
*/
}
Ответ 2
fixedRate: используется для запуска метода задания за каждые миллисекунды. Не важно, завершила ли задание свою предыдущую задачу.
fixedDelay: он используется для запуска метода задания последовательно с заданным временем ожидания в миллисекундах между задачами.
Когда использовать "fixedRate": fixedRate является подходящим, если он не должен превышать размер памяти и пула потоков. Если входящие задачи не заканчиваются быстро, это может закончиться "Исключением из памяти",
Когда использовать "fixedDelay": если каждая выполняемая задача имеет отношение друг к другу, и им нужно подождать до того, как закончится предыдущий, то подходит fixedRate. Если время fixedDelay установлено тщательно, это также позволит текущим потокам достаточно времени, чтобы закончить работу до начала новой задачи
Ответ 3
"fixedRate": ждет X millis от начала предыдущего выполнения до начала следующего выполнения. Если текущее исполнение превышает интервал "fixedRate", следующее выполнение ставится в очередь, но только следующее. Он не будет создавать серии очередей
private static int i = 0;
@Scheduled(initialDelay=1000, fixedRate=1000)
public void testScheduling() throws InterruptedException {
System.out.println("Started : "+ ++i);
Thread.sleep(4000);
System.out.println("Finished : "+ i);
}
Вывод:
Начато: 1
Закончено: 1//через 4 секунды
Начато: 2//немедленно без ожидания 1 с, как указано в фиксированной скорости
Закончено: 2//через 4 секунды
и так далее
"fixedDelay": ждет X millis с конца предыдущего исполнения перед началом следующего выполнения. Не имеет значения, сколько времени занимает текущее исполнение, следующее выполнение запускается после добавления интервала "fixedDelay" до конца текущего выполнения. Он не ставит в очередь следующее выполнение.
private static int i = 0;
@Scheduled(initialDelay=1000, fixedDelay=1000)
public void testScheduling() throws InterruptedException {
System.out.println("Started : "+ ++i);
Thread.sleep(4000);
System.out.println("Finished : "+ i);
}
Вывод:
Начато: 1
Закончено: 1//через 4 секунды. Начало: 2//ждет 1 секунду, как указано в fixedDelay. Закончено: 2//через 4 секунды. Начало: 3//через 1 секунду.
и так далее
Ответ 4
Fixed Delay: специально контролирует следующее время выполнения при завершении последнего выполнения.
Фиксированная ставка: позволяет Spring запускать задание на периодические интервалы, даже если последний вызов может быть запущен.
Ответ 5
Необходимо уточнить, что fixedRate
не означает, что выполнение начинается с определенного интервала времени.
Если один исполнение стоит слишком много времени (больше, чем по фиксированной ставке), то следующий выполнение начнется только ПОСЛЕ того, как предыдущий заканчивается, если @Async
и @EnableAsync
не предусмотрены. Следующие исходные коды, которые являются частью реализации Spring ThreadPoolTaskScheduler
объясняют, почему:
@Override
public void run() {
Date actualExecutionTime = new Date();
super.run();
Date completionTime = new Date();
synchronized (this.triggerContextMonitor) {
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
if (!this.currentFuture.isCancelled()) {
schedule();
}
}
}
Вы можете видеть, что только после завершения предыдущей задачи (super.run()
) следующая задача запланирована (schedule()
). С @Async
и @EnableAsync
super.run()
- это асинхронная функция, которая будет немедленно возвращаться, поэтому следующей задаче не нужно ждать, пока предыдущий не завершится.