Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should Timertask.scheduleAtFixedRate do if the clock changes?

We want to run a task every 1000 seconds (say).

So we have

timer.scheduleAtFixedRate(task, delay, interval);

Mostly, this works fine. However, this is an embedded system and the user can change the real time clock. If they set it to a time in the past after we set up the timer, it seems the timer doesn't execute until the original real-time date/time. So if they set it back 3 days, the timer doesn't execute for 3 days :(

Is this permissible behaviour, or a defect in the Java library? The Oracle javadocs don't seem to mention anything about the dependency or not on the underlying value of the system clock.

If it's permissible, how do we spot this clock change and reschedule our timers?

like image 572
The Archetypal Paul Avatar asked Jul 11 '13 08:07

The Archetypal Paul


People also ask

What is the relationship between Timer and TimerTask?

Timer and TimerTask are java util classes that we use to schedule tasks in a background thread. Basically, TimerTask is the task to perform, and Timer is the scheduler.

What does Timer schedule do?

The schedule(TimerTask task,long delay,long period) method is used to schedule the specified task for repeated fixed-delay execution, beginning after the specified delay.

Is TimerTask a thread?

Both TimerTask and Thread execute asynchronously, but TimerTask is scheduled to execute at fixed intervals while Thread is not.

What is java Timer thread?

A facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals. Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially.


1 Answers

Looking at the source of Timer for Java 1.7, it appears that is uses System.currentTimeMillis() to determine the next execution of a task.

However, looking at the source of ScheduledThreadPoolExecutor, it uses System.nanoTime().

Which means you won't see that behaviour if you use one in place of a Timer. To create one, use, for instance, Executors.newScheduledThreadPool().

Why you wouldn't see this behaviour is because of what the doc for System.nanoTime() says:

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary origin time [emphasis mine].

As to whether this is a bug in Timer, maybe...

Note that unlike a ScheduledExecutorService, a Timer supports absolute time, and maybe this explains its use of System.currentTimeMillis(); also, Timer has been there since Java 1.3 while System.nanoTime() only appears in 1.5.

But a consequence of using System.currentTimeMillis() is that Timer is sensitive to the system date/time... And that is not documented in the javadoc.

like image 184
fge Avatar answered Oct 13 '22 10:10

fge