如何安排每小时的工作?

时间:2022-04-10 01:12:06

I'm developing a service that suppose to start of every hour repeating exactly on the hour (1:00PM, 2:00PM, 3:00PM, etc.).

我正在开发一项服务,假设每个小时的开始都是在一个小时重复(1点,2点,3点,等等)。

I tried following but it has one problem that for first time i have to run the program exactly at start of hour and then this scheduler will repeat it.

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

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

Any suggestion to repeat my task regardless when i run the program?

无论我什么时候运行程序,是否有重复任务的建议?

Regards, Imran

问候,伊姆兰

4 个解决方案

#1


12  

I would also suggest Quartz for this. But the above code can be made to run first at the start of the hour using the initialDelay parameter.

我也建议你用石英。但是可以使用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


7  

If you can afford to use an external library, then Quartz provides very flexible and easy to use scheduling modes. For example cron mode should be perfect for your case. Below a simple example of scheduling a certain Job to be executed every hour:

如果您能够负担得起使用外部库的费用,Quartz提供了非常灵活和易于使用的调度模式。例如,cron模式应该非常适合您的情况。下面是一个简单的例子,即每个小时都要执行特定的任务:

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

Have a look at the tutorial and examples to find which formulations suits your tastes. They also show how to deal with errors.

看看教程和例子,找到适合你口味的配方。它们还展示了如何处理错误。

#3


6  

The millisToNextHour method in krishnakumarp's answer can be made more compact and straightforward in Java 8, which would result in the following code:

在krishnakumarp的答案中,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);
}

#4


1  

If you are using the spring in your service than you can directly use the annotation based scheduler @Schedule annotation which takes cron expression as a parameter or the delay in milliseconds, just add this annotation above the method you want to execute and this method will be executed. Enjoy...........

如果在服务中使用spring,而不能直接使用基于注释的scheduler @Schedule注释,该注释将cron表达式作为参数或以毫秒为单位的延迟,那么只需在要执行的方法之上添加此注释,该方法将被执行。享受...........

#1


12  

I would also suggest Quartz for this. But the above code can be made to run first at the start of the hour using the initialDelay parameter.

我也建议你用石英。但是可以使用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


7  

If you can afford to use an external library, then Quartz provides very flexible and easy to use scheduling modes. For example cron mode should be perfect for your case. Below a simple example of scheduling a certain Job to be executed every hour:

如果您能够负担得起使用外部库的费用,Quartz提供了非常灵活和易于使用的调度模式。例如,cron模式应该非常适合您的情况。下面是一个简单的例子,即每个小时都要执行特定的任务:

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

Have a look at the tutorial and examples to find which formulations suits your tastes. They also show how to deal with errors.

看看教程和例子,找到适合你口味的配方。它们还展示了如何处理错误。

#3


6  

The millisToNextHour method in krishnakumarp's answer can be made more compact and straightforward in Java 8, which would result in the following code:

在krishnakumarp的答案中,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);
}

#4


1  

If you are using the spring in your service than you can directly use the annotation based scheduler @Schedule annotation which takes cron expression as a parameter or the delay in milliseconds, just add this annotation above the method you want to execute and this method will be executed. Enjoy...........

如果在服务中使用spring,而不能直接使用基于注释的scheduler @Schedule注释,该注释将cron表达式作为参数或以毫秒为单位的延迟,那么只需在要执行的方法之上添加此注释,该方法将被执行。享受...........