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

This pull request fixes a long standing issue in the MonocleTimer class whereby 
it has a dependency on the java.uti.Timer class which is dependent on system 
time and can cause UI freezes for seconds/minutes/hours/days/years dependent 
upon how far back in time the system clock is set by either a user manually or 
NTP. This looks like it is because the Timer class will wait for (executionTime 
- currentTime) before proceeding if a task hasn't fired yet.

https://hg.openjdk.java.net/jdk10/master/file/be620a591379/src/java.base/share/classes/java/util/Timer.java#l553

For a long running embedded device with a UI like IOT devices this is pretty 
disastrous.
We recently re-discovered this issue whilst testing such a device before going 
into production.

The MonocleTimer class is used by MonocleApplication and QuantumToolkit class 
to create its pulseTimer for emebdded systems and sets it up to fire 
periodically inline with the requested pulse frequency which by default is 60Hz 
resulting in a pulse interval of 16ms. 

It is well documented that for implementations that wish to measure elapsed 
time ScheduledThreadPoolExecutor should be used as a replacement for 
java.util.Timer class.

Java Concurrency In Practice:
https://pdfs.semanticscholar.org/3650/4bc31d3b2c5c00e5bfee28ffc5d403cc8edd.pdf 
(page 77)

"The Timer facility manages the execution of deferred ("run this task in 100 
ms") and periodic ("run this task every 10ms") tasks. However, Timer has some 
drawbacks, and ScheduledThreadPoolExecutor should be thought of as its 
replacement."

With the original implementation, if I set the date.time back 8 years for 
example the UI freezes up indefinitely (I cant wait 8 years). Repeating the 
same test with the proposed implementation has no affect on the UI and it runs 
as normal.

The proposed solution has been tested on an Arm iMX6 board.

Whist testing in isolation the MonocleTimer class with no work to do on each 
pulse, it looks like the change from Timer class to ScheduledThreadPoolExecutor 
also has brought with it a greater accuracy of when the pulses are fired.

The following results were observed when running MonocleTimer at 60Hz for 1 
minute. It appears that we get a higher frequency of pulses hitting the 16ms 
mark with the replacement solution


x86-64 linux desktop:

---- Timer class ----
NumSamples: 3599
Mean: 16.230063906640734
StdDev: 0.45021901536403147
Median: 16
Mode: 16, freq: 2714, perc: 75.40983606557377%

 
---- Scheduler class ----
NumSamples: 3599
Mean: 16.0
StdDev: 0.0
Median: 16
Mode: 16, freq: 3599, perc: 100.0%



Arm linux iMX6:

---- Timer class ----
NumSamples: 3599
Mean: 16.182272853570435
StdDev: 0.4224950723394174
Median: 16
Mode: 16, freq: 2837, perc: 78.82745207001946%


---- Scheduler class ----
NumSamples: 3599
Mean: 15.995554320644624
StdDev: 0.3666906549602725
Median: 16
Mode: 16, freq: 3468, perc: 96.3601000277855%

-------------

Commits:
 - 3c22d205: 8176499: Remove MonocleTimer dependency on system time

Changes: https://git.openjdk.java.net/jfx/pull/117/files
 Webrev: https://webrevs.openjdk.java.net/jfx/117/webrev.00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8176499
  Stats: 17 lines in 1 file changed: 3 ins; 8 del; 6 mod
  Patch: https://git.openjdk.java.net/jfx/pull/117.diff
  Fetch: git fetch https://git.openjdk.java.net/jfx pull/117/head:pull/117

PR: https://git.openjdk.java.net/jfx/pull/117

Reply via email to