какая разница между фиксированной ставкой и фиксированной задержкой в расписании весны?

Я выполняю запланированные задачи с использованием 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() - это асинхронная функция, которая будет немедленно возвращаться, поэтому следующей задаче не нужно ждать, пока предыдущий не завершится.