Как планировать задачу для запуска каждого часа
Я разрабатываю услугу, которая предполагает начало каждого часа, повторяющегося точно в час (1:00 PM, 2:00 PM, 3:00 PM и т.д.).
Я пробовал следовать, но у меня есть одна проблема: я впервые должен запустить программу именно в начале часа, а затем этот планировщик повторит ее.
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleWithFixedDelay(new MyTask(), 0, 1, TimeUnit.HOURS);
Любое предложение повторить мою задачу независимо от того, когда я запускаю программу?
С уважением,
Имран
Ответы
Ответ 1
Я также предложил бы Quartz. Но приведенный выше код может быть выполнен для запуска сначала в начале часа с использованием параметра initialDelay.
Calendar calendar = Calendar.getInstance();
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new MyTask(), millisToNextHour(calendar), 60*60*1000, TimeUnit.MILLISECONDS);
private static long millisToNextHour(Calendar calendar) {
int minutes = calendar.get(Calendar.MINUTE);
int seconds = calendar.get(Calendar.SECOND);
int millis = calendar.get(Calendar.MILLISECOND);
int minutesToNextHour = 60 - minutes;
int secondsToNextHour = 60 - seconds;
int millisToNextHour = 1000 - millis;
return minutesToNextHour*60*1000 + secondsToNextHour*1000 + millisToNextHour;
}
Ответ 2
Если вы можете позволить себе использовать внешнюю библиотеку, Quartz обеспечивает очень гибкие и простые в использовании режимы планирования. Например, режим cron
должен быть идеальным для вашего случая. Ниже простой пример планирования определенного Job, который должен выполняться каждый час:
quartzScheduler.scheduleJob(
myJob, newTrigger().withIdentity("myJob", "group")
.withSchedule(cronSchedule("0 * * * * ?")).build());
Посмотрите tutorial и examples найти, какие формулировки соответствуют вашим вкусам. Они также показывают, как бороться с ошибками.
Ответ 3
Метод millisToNextHour
в krishnakumarp answer можно сделать более компактным и понятным в Java 8, что приведет к следующему коду:
public void schedule() {
ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
scheduledExecutor.scheduleAtFixedRate(new MyTask(), millisToNextHour(), 60*60*1000, TimeUnit.MILLISECONDS);
}
private long millisToNextHour() {
LocalDateTime nextHour = LocalDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS);
return LocalDateTime.now().until(nextHour, ChronoUnit.MILLIS);
}
Ответ 4
Если вы используете spring в своей службе, чем можете напрямую использовать аннотацию на основе планировщика @Schedule, которая принимает выражение cron в качестве параметра или задержку в миллисекундах, просто добавьте эту аннотацию выше метода, который вы хотите выполнить и этот метод будет выполнен. Наслаждайтесь...........