java.util.Timer is good for wall time scheduling?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

java.util.Timer is good for wall time scheduling?

JSR166 Concurrency mailing list
There is an interesting question on StackOverflow with an evidence of rather extreme time drift when a task is scheduled periodically using ScheduledThreadPoolExecutor: https://stackoverflow.com/questions/56571647/why-does-the-java-scheduler-exhibit-significant-time-drift-on-windows. java.util.Timer appears to be a workaround for that problem. It looks to me that java.util.Timer is an only tool offered by JDK suitable for wall-clock time (cron-style) scheduling.

In this context, I would like to recall the discussion of hibernation and ScheduledThreadPoolExecutor behavior (https://bugs.openjdk.java.net/browse/JDK-8146527; the discussion thread in this list: http://cs.oswego.edu/pipermail/concurrency-interest/2016-January/014817.html). It seems actually that the desired case of "sending an e-mail each hour" could be pretty easily coded with Timer:

new Timer().scheduleAtFixedRate(new TimerTask() {
  long minutes = 0;
  @Override public void run() {
      if (minutes % 60 == 0 &&
          System.currentTimeMillis() - scheduledExecutionTime() < MINUTES.toMillis(1)) {
       sendEmail();
     }
     minutes++;
   }
}, nextRoundMinuteDate(), MINUTES.toMillis(1));

With this, I have a few questions:

 1) Should the Javadoc for Timer, which currently says:

"Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer."

be amended, perhaps, with the following passage: ", except that Timer may be more appropriate for scheduling recurring activities that are sensitive to absolute time because Timer is more robust to the clock drift than ScheduledThreadPoolExecutor."


"Also note that we (JSR166 expert group) explicitly killed the absolute-time schedule methods due to their problematic nature (as evidenced by bugs reports on java.util.Timer functionality) - and that wasn't even considering PC sleep/suspend/hibernate issues."

Could somebody please kindly point to these bugs on Timer functionality in JDK issue tracker, or note whether they were fixed?

3) Quite unrelated to the previous, but since Timer is discussed rarely: would it make sense to replace Timer's threadReaper field which is currently an Object with a finalize() method overridden with a Cleaner?

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: java.util.Timer is good for wall time scheduling?

JSR166 Concurrency mailing list

Hi Roman,

 

Regarding:

 

“Could somebody please kindly point to these bugs on Timer functionality in JDK issue tracker, or note whether they were fixed?”

 

See for example

 

https://bugs.openjdk.java.net/browse/JDK-4290274

 

and linked bugs.

 

Cheers,

David

 

From: Roman Leventov
Sent: Monday, January 6, 2020 5:23 AM
To: concurrency-interest <[hidden email]>; [hidden email]; [hidden email]
Subject: java.util.Timer is good for wall time scheduling?

 

There is an interesting question on StackOverflow with an evidence of rather extreme time drift when a task is scheduled periodically using ScheduledThreadPoolExecutor: https://stackoverflow.com/questions/56571647/why-does-the-java-scheduler-exhibit-significant-time-drift-on-windows. java.util.Timer appears to be a workaround for that problem. It looks to me that java.util.Timer is an only tool offered by JDK suitable for wall-clock time (cron-style) scheduling.

 

In this context, I would like to recall the discussion of hibernation and ScheduledThreadPoolExecutor behavior (https://bugs.openjdk.java.net/browse/JDK-8146527; the discussion thread in this list: http://cs.oswego.edu/pipermail/concurrency-interest/2016-January/014817.html). It seems actually that the desired case of "sending an e-mail each hour" could be pretty easily coded with Timer:

 

new Timer().scheduleAtFixedRate(new TimerTask() {

  long minutes = 0;

  @Override public void run() {

      if (minutes % 60 == 0 &&

          System.currentTimeMillis() - scheduledExecutionTime() < MINUTES.toMillis(1)) {

       sendEmail();

     }

     minutes++;

   }

}, nextRoundMinuteDate(), MINUTES.toMillis(1));

 

With this, I have a few questions:

 

 1) Should the Javadoc for Timer, which currently says:

 

"Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer."

 

be amended, perhaps, with the following passage: ", except that Timer may be more appropriate for scheduling recurring activities that are sensitive to absolute time because Timer is more robust to the clock drift than ScheduledThreadPoolExecutor."

 

 

"Also note that we (JSR166 expert group) explicitly killed the absolute-time schedule methods due to their problematic nature (as evidenced by bugs reports on java.util.Timer functionality) - and that wasn't even considering PC sleep/suspend/hibernate issues."

 

Could somebody please kindly point to these bugs on Timer functionality in JDK issue tracker, or note whether they were fixed?

 

3) Quite unrelated to the previous, but since Timer is discussed rarely: would it make sense to replace Timer's threadReaper field which is currently an Object with a finalize() method overridden with a Cleaner?


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: java.util.Timer is good for wall time scheduling?

JSR166 Concurrency mailing list
Thank you.


"The software should continue printing numbers. This is a real problem when the daylight savings time arrives (summer/winter)."

May there be a bug in JVM/macOS? Daylight savings should not affect currentTimeMillis(). Assuming the reporter actually experienced this problem, rather than observed the delay from a manual time reset and then extrapolated to the daylight saving case.


I think there is something that definitely could be improved: a reference to "countdown timer that ticks once every second for ten seconds" use case removed from Timer Javadocs, because it definitely looks like the case where ScheduledThreadPoolExecutor is a superior alternative all around.

Regarding a timer freeze when time is set backward, a possible solution might be that TimerThread.mainLoop() detects the time going backward, and in this case, walks through the queue and examines each TimerTask scheduled at a fixed rate, "unwinding" it appropriately  (this may result in rebuilding the whole queue, but that shouldn't be practically a performance concern). The only semantic problem with this is that TimerTask.scheduledExecutionTime() may now go backward in successive executions, which might be unexpected by some clients.

On Mon, 6 Jan 2020 at 00:54, David Holmes <[hidden email]> wrote:

Hi Roman,

 

Regarding:

 

“Could somebody please kindly point to these bugs on Timer functionality in JDK issue tracker, or note whether they were fixed?”

 

See for example

 

https://bugs.openjdk.java.net/browse/JDK-4290274

 

and linked bugs.

 

Cheers,

David

 

From: Roman Leventov
Sent: Monday, January 6, 2020 5:23 AM
To: concurrency-interest <[hidden email]>; [hidden email]; [hidden email]
Subject: java.util.Timer is good for wall time scheduling?

 

There is an interesting question on StackOverflow with an evidence of rather extreme time drift when a task is scheduled periodically using ScheduledThreadPoolExecutor: https://stackoverflow.com/questions/56571647/why-does-the-java-scheduler-exhibit-significant-time-drift-on-windows. java.util.Timer appears to be a workaround for that problem. It looks to me that java.util.Timer is an only tool offered by JDK suitable for wall-clock time (cron-style) scheduling.

 

In this context, I would like to recall the discussion of hibernation and ScheduledThreadPoolExecutor behavior (https://bugs.openjdk.java.net/browse/JDK-8146527; the discussion thread in this list: http://cs.oswego.edu/pipermail/concurrency-interest/2016-January/014817.html). It seems actually that the desired case of "sending an e-mail each hour" could be pretty easily coded with Timer:

 

new Timer().scheduleAtFixedRate(new TimerTask() {

  long minutes = 0;

  @Override public void run() {

      if (minutes % 60 == 0 &&

          System.currentTimeMillis() - scheduledExecutionTime() < MINUTES.toMillis(1)) {

       sendEmail();

     }

     minutes++;

   }

}, nextRoundMinuteDate(), MINUTES.toMillis(1));

 

With this, I have a few questions:

 

 1) Should the Javadoc for Timer, which currently says:

 

"Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer."

 

be amended, perhaps, with the following passage: ", except that Timer may be more appropriate for scheduling recurring activities that are sensitive to absolute time because Timer is more robust to the clock drift than ScheduledThreadPoolExecutor."

 

 

"Also note that we (JSR166 expert group) explicitly killed the absolute-time schedule methods due to their problematic nature (as evidenced by bugs reports on java.util.Timer functionality) - and that wasn't even considering PC sleep/suspend/hibernate issues."

 

Could somebody please kindly point to these bugs on Timer functionality in JDK issue tracker, or note whether they were fixed?

 

3) Quite unrelated to the previous, but since Timer is discussed rarely: would it make sense to replace Timer's threadReaper field which is currently an Object with a finalize() method overridden with a Cleaner?


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: java.util.Timer is good for wall time scheduling?

JSR166 Concurrency mailing list
I've created a project CronScheduler that aims to solve time/clock drift, system time resets, and suspend mode issues with ScheduledThreadPoolExecutor and Timer: https://medium.com/@leventov/cronscheduler-a-reliable-java-scheduler-for-external-interactions-cb7ce4a4f2cd. It uses similar idea as mentioned by Josh Bloch in this comment: https://bugs.openjdk.java.net/browse/JDK-4290274?focusedCommentId=12563675&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-12563675

The code of CronScheduler is based on public domain JSR-166 code for TPE and SchTPE. Here are some minor issues that I've noticed with the code:

 - SchTPE.shutdownNow() Javadoc says that it returns "a list of task that never commenced execution". But I think it also returns periodic tasks. So this may sound confusing.
 - It may make sense to add toString() impl to ScheduledFutureTask, FutureTask, or RunnableAdapter, because AbortPolicy adds runnable.toString() to the error message, which is an instance of ScheduledFutureTask in case of SchTPE, which may make debugging harder because it will not allow to see from where the rejected task originates (of course the final runnable also doesn't have toString(), but it may be of the form OriginatingClass$1...)
 - CompletableFuture.toString() Javadoc says the messages are "Completed Normally" and "Completed Exceptionally", but actual messages in code have different case: "Completed normally" and "Completed Exceptionally"
 - Possible improvement: cancelled tasks may be opportunistically purged during the queue restructuring process in DelayedWorkQueue.offer().

On Mon, 6 Jan 2020 at 12:33, Roman Leventov <[hidden email]> wrote:
Thank you.


"The software should continue printing numbers. This is a real problem when the daylight savings time arrives (summer/winter)."

May there be a bug in JVM/macOS? Daylight savings should not affect currentTimeMillis(). Assuming the reporter actually experienced this problem, rather than observed the delay from a manual time reset and then extrapolated to the daylight saving case.


I think there is something that definitely could be improved: a reference to "countdown timer that ticks once every second for ten seconds" use case removed from Timer Javadocs, because it definitely looks like the case where ScheduledThreadPoolExecutor is a superior alternative all around.

Regarding a timer freeze when time is set backward, a possible solution might be that TimerThread.mainLoop() detects the time going backward, and in this case, walks through the queue and examines each TimerTask scheduled at a fixed rate, "unwinding" it appropriately  (this may result in rebuilding the whole queue, but that shouldn't be practically a performance concern). The only semantic problem with this is that TimerTask.scheduledExecutionTime() may now go backward in successive executions, which might be unexpected by some clients.

On Mon, 6 Jan 2020 at 00:54, David Holmes <[hidden email]> wrote:

Hi Roman,

 

Regarding:

 

“Could somebody please kindly point to these bugs on Timer functionality in JDK issue tracker, or note whether they were fixed?”

 

See for example

 

https://bugs.openjdk.java.net/browse/JDK-4290274

 

and linked bugs.

 

Cheers,

David

 

From: Roman Leventov
Sent: Monday, January 6, 2020 5:23 AM
To: concurrency-interest <[hidden email]>; [hidden email]; [hidden email]
Subject: java.util.Timer is good for wall time scheduling?

 

There is an interesting question on StackOverflow with an evidence of rather extreme time drift when a task is scheduled periodically using ScheduledThreadPoolExecutor: https://stackoverflow.com/questions/56571647/why-does-the-java-scheduler-exhibit-significant-time-drift-on-windows. java.util.Timer appears to be a workaround for that problem. It looks to me that java.util.Timer is an only tool offered by JDK suitable for wall-clock time (cron-style) scheduling.

 

In this context, I would like to recall the discussion of hibernation and ScheduledThreadPoolExecutor behavior (https://bugs.openjdk.java.net/browse/JDK-8146527; the discussion thread in this list: http://cs.oswego.edu/pipermail/concurrency-interest/2016-January/014817.html). It seems actually that the desired case of "sending an e-mail each hour" could be pretty easily coded with Timer:

 

new Timer().scheduleAtFixedRate(new TimerTask() {

  long minutes = 0;

  @Override public void run() {

      if (minutes % 60 == 0 &&

          System.currentTimeMillis() - scheduledExecutionTime() < MINUTES.toMillis(1)) {

       sendEmail();

     }

     minutes++;

   }

}, nextRoundMinuteDate(), MINUTES.toMillis(1));

 

With this, I have a few questions:

 

 1) Should the Javadoc for Timer, which currently says:

 

"Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer."

 

be amended, perhaps, with the following passage: ", except that Timer may be more appropriate for scheduling recurring activities that are sensitive to absolute time because Timer is more robust to the clock drift than ScheduledThreadPoolExecutor."

 

 

"Also note that we (JSR166 expert group) explicitly killed the absolute-time schedule methods due to their problematic nature (as evidenced by bugs reports on java.util.Timer functionality) - and that wasn't even considering PC sleep/suspend/hibernate issues."

 

Could somebody please kindly point to these bugs on Timer functionality in JDK issue tracker, or note whether they were fixed?

 

3) Quite unrelated to the previous, but since Timer is discussed rarely: would it make sense to replace Timer's threadReaper field which is currently an Object with a finalize() method overridden with a Cleaner?


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest