有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在开发一个服务,假设每小时都开始,并在一小时内重复(下午1:00、下午2:00、下午3:00等)

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

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

有没有建议在我运行程序时重复我的任务

问候, 伊姆兰


共 (4) 个答案

  1. # 1 楼答案

    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);
    }
    
  2. # 2 楼答案

    我还建议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;
    }
    
  3. # 3 楼答案

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

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

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

  4. # 4 楼答案

    如果您在服务中使用spring,那么您可以直接使用基于注释的调度器@Schedule annotation,该调度器以cron expression作为参数或延迟(以毫秒为单位),只需将此注释添加到您想要执行的方法之上,此方法就会被执行。享受