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

时间:2012-04-18 06:47:34

标签: java scheduled-tasks scheduling

我正在开发一种服务,假设每小时开始时间完全重复(下午1:00,下午2:00,下午3:00等)。

我试过以下但是它有一个问题,我第一次必须在小时开始时运行程序,然后这个调度程序将重复它。

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleWithFixedDelay(new MyTask(), 0, 1, TimeUnit.HOURS);

任何建议在我运行程序时重复我的任务?

此致 姆兰

4 个答案:

答案 0 :(得分:13)

我还建议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;
}

答案 1 :(得分:8)

krishnakumarp' s 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);
}

答案 2 :(得分:7)

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

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

查看tutorialexamples,了解哪些配方符合您的口味。他们还展示了如何处理错误。

答案 3 :(得分:1)

如果您在服务中使用spring而不是直接使用基于注释的调度程序@Schedule注释,该注释将cron表达式作为参数或延迟(以毫秒为单位),只需将此注释添加到要执行的方法上方即可方法将被执行。享受...........