如何安排每小时开始的任务

Posted

技术标签:

【中文标题】如何安排每小时开始的任务【英文标题】:How to schedule task for start of every hour 【发布时间】:2012-04-29 13:27:42 【问题描述】:

我正在开发一项服务,该服务假设每小时开始,准确地在整点重复(下午 1:00、下午 2:00、下午 3:00 等)。

我尝试了以下操作,但有一个问题是我第一次必须在开始时准确地运行程序,然后这个调度程序会重复它。

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;

【讨论】:

我们将使用 scheduleWithFixedDelay 还是 scheduleAtFixedDelay ?我想我们将使用 scheduleAtFixedDelay。否则会重复增加执行时间。 是的。在您的情况下,您应该使用 scheduleAtFixedRate。更新了答案 这很有帮助,但请注意,此代码将比一小时开始晚 1 分 1 秒运行任务。【参考方案2】:

krishnakumarp 的 answer 中的 millisToNextHour 方法在 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);

【讨论】:

【参考方案3】:

如果您负担得起使用外部库,那么Quartz 提供了非常灵活且易于使用的调度模式。例如cron 模式应该非常适合您的情况。下面是一个安排某个Job每小时执行的简单示例:

quartzScheduler.scheduleJob(
    myJob, newTrigger().withIdentity("myJob", "group")
                       .withSchedule(cronSchedule("0 * * * * ?")).build());

查看tutorial 和examples,找到适合您口味的配方。它们还展示了如何处理错误。

【讨论】:

【参考方案4】:

如果你在你的服务中使用spring,那么你可以直接使用基于注解的调度器@Schedule注解,它以cron表达式为参数或以毫秒为单位的延迟,只需在你要执行的方法上方添加这个注解,这个方法将被执行。享受............

【讨论】:

以上是关于如何安排每小时开始的任务的主要内容,如果未能解决你的问题,请参考以下文章

每小时安排后台任务swift 4

我想通过使用cron表达式设置每24小时安排一个任务

Laravel每小时在08:00,12:00,16:00和20:00,22:00运行任务

使用 SilverStripe 的计划任务

在 python 上安排任务

schtasks /create(有一个每天运行并每小时重复的任务