【问题标题】: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);

有什么建议可以在我运行程序时重复我的任务?

问候, 伊姆兰

【问题讨论】:

    标签: java scheduled-tasks scheduling


    【解决方案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());
      

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-12
          • 2018-07-05
          相关资源
          最近更新 更多