Scheduling periodic tasks and clock drift

前端 未结 3 464
耶瑟儿~
耶瑟儿~ 2021-01-23 01:09

I would like to schedule a periodic task which executes every X hours. I have a service which is written in Java and I was thinking of creating a long running background thread

相关标签:
3条回答
  • 2021-01-23 01:25

    Java provides a java.util.Timer class that is designed to execute a task on a background thread. One of the modes of operation is "repeated execution at regular intervals". There are fixed-delay and fixed-rate execution methods that can be used, depending on your exact needs.

    Java 5 added a java.util.concurrent.ScheduledThreadPoolExecutor class that is more flexible than Timer, but also offers fixed-delay and fixed-rate execution methods.

    If you need such precise timing that these aren't suitable, I'm not sure that Java is an appropriate solution. You would be starting to enter the realm of a real-time system. At this point, you should likely be looking for other options.

    0 讨论(0)
  • 2021-01-23 01:29

    Is clock drift on my host an issue I should be worried about?

    Yes, clock drift can be an issue when using ScheduledThreadPoolExecutor.

    CronScheduler is specifically designed to be proof against clock drift.

    Example usage:

    Duration syncPeriod = Duration.ofMinutes(1);
    CronScheduler cron = CronScheduler.create(syncPeriod);
    
    // If you need just precisely "once every X hours", irrespective of the
    // starting time
    cron.scheduleAtFixedRate(0, X, TimeUnit.HOURS, runTimeMillis -> {
        // Do the task
    });
    
    // If you need "once every X hours" in terms of wall clock time,
    // in some time zone:
    ZoneId myTZ = ZoneId.systemDefault();
    cron.scheduleAtRoundTimesInDay(Duration.ofHours(X), myTZ, runTimeMillis -> {
        // Do the task
    });
    

    See Javadocs for scheduleAtRoundTimesInDay.

    0 讨论(0)
  • 2021-01-23 01:39

    If you are worried, write a test process and run it on the target platform. Using the feature you plan to use for the real process (like ScheduledExecutorService), schedule a task to log the host time every 24 hours. If the host doesn't use NTP to keep its clock synchronized, perhaps you could also make call to a time-keeping web service and log that too. After a few days, you should have a good sense of whether you need a method to correct for drift.

    My guess is that the built-in scheduler will be accurate to less than a second per day.

    0 讨论(0)
提交回复
热议问题