Чем scheduleAtFixedRate отличается от scheduleWithFixedDelay?
Оба метода запускают периодическую задачу, но отсчитывают интервал по-разному. Если выбрать не тот режим, долгие операции могут запускаться чаще, чем ожидает команда.
При фиксированной частоте следующий запуск привязан к расписанию, а не к окончанию предыдущего:
scheduler.scheduleAtFixedRate(
this::refresh, 0, 30, TimeUnit.SECONDS);
Если обновление занимает 8 секунд, следующий запуск всё равно планируется через 30 секунд от предыдущего старта. Один и тот же периодический task не выполняется параллельно сам с собой, но при долгой операции новый запуск может начаться почти сразу после её завершения.
Фиксированная задержка отсчитывается после завершения операции:
scheduler.scheduleWithFixedDelay(
this::refresh, 0, 30, TimeUnit.SECONDS);
При работе в 8 секунд между завершением одного запуска и началом следующего пройдёт 30 секунд.
Есть ещё важный нюанс. Если периодический запуск завершится с исключением, следующие вызовы подавляются:
Runnable safeRefresh = () -> {
try { refresh(); }
catch (RuntimeException error) { logger.error("Refresh failed", error); }
};
Сохраняй ScheduledFuture, если задачу нужно остановить до остановки всего executor:
ScheduledFuture<?> job = scheduler.scheduleWithFixedDelay(
safeRefresh, 0, 30, TimeUnit.SECONDS);
job.cancel(false);
Выбирай fixed rate для привязки к расписанию, а fixed delay для паузы после каждой работы.
Просмотры: 210