@@ -142,7 +142,7 @@ public static ThreadPoolType fromType(String type) {
142142
143143 private final ScheduledThreadPoolExecutor scheduler ;
144144
145- private final EstimatedTimeThread estimatedTimeThread ;
145+ private final CachedTimeThread cachedTimeThread ;
146146
147147 static final ExecutorService DIRECT_EXECUTOR = EsExecutors .newDirectExecutorService ();
148148
@@ -213,16 +213,33 @@ public ThreadPool(final Settings settings, final ExecutorBuilder<?>... customBui
213213 this .scheduler .setRemoveOnCancelPolicy (true );
214214
215215 TimeValue estimatedTimeInterval = ESTIMATED_TIME_INTERVAL_SETTING .get (settings );
216- this .estimatedTimeThread = new EstimatedTimeThread (EsExecutors .threadName (settings , "[timer]" ), estimatedTimeInterval .millis ());
217- this .estimatedTimeThread .start ();
216+ this .cachedTimeThread = new CachedTimeThread (EsExecutors .threadName (settings , "[timer]" ), estimatedTimeInterval .millis ());
217+ this .cachedTimeThread .start ();
218218 }
219219
220- public long estimatedTimeInMillis () {
221- return estimatedTimeThread .estimatedTimeInMillis ();
220+ /**
221+ * Returns a value of milliseconds that may be used for relative time calculations.
222+ *
223+ * This method should only be used for calculating time deltas. For an epoch based
224+ * timestamp, see {@link #absoluteTimeInMillis()}.
225+ */
226+ public long relativeTimeInMillis () {
227+ return cachedTimeThread .relativeTimeInMillis ();
228+ }
229+
230+ /**
231+ * Returns the value of milliseconds since UNIX epoch.
232+ *
233+ * This method should only be used for exact date/time formatting. For calculating
234+ * time deltas that should not suffer from negative deltas, which are possible with
235+ * this method, see {@link #relativeTimeInMillis()}.
236+ */
237+ public long absoluteTimeInMillis () {
238+ return cachedTimeThread .absoluteTimeInMillis ();
222239 }
223240
224241 public Counter estimatedTimeInMillisCounter () {
225- return estimatedTimeThread .counter ;
242+ return cachedTimeThread .counter ;
226243 }
227244
228245 public ThreadPoolInfo info () {
@@ -342,8 +359,8 @@ public ScheduledFuture<?> schedule(TimeValue delay, String executor, Runnable co
342359 }
343360
344361 public void shutdown () {
345- estimatedTimeThread .running = false ;
346- estimatedTimeThread .interrupt ();
362+ cachedTimeThread .running = false ;
363+ cachedTimeThread .interrupt ();
347364 scheduler .shutdown ();
348365 for (ExecutorHolder executor : executors .values ()) {
349366 if (executor .executor () instanceof ThreadPoolExecutor ) {
@@ -353,8 +370,8 @@ public void shutdown() {
353370 }
354371
355372 public void shutdownNow () {
356- estimatedTimeThread .running = false ;
357- estimatedTimeThread .interrupt ();
373+ cachedTimeThread .running = false ;
374+ cachedTimeThread .interrupt ();
358375 scheduler .shutdownNow ();
359376 for (ExecutorHolder executor : executors .values ()) {
360377 if (executor .executor () instanceof ThreadPoolExecutor ) {
@@ -371,7 +388,7 @@ public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedE
371388 }
372389 }
373390
374- estimatedTimeThread .join (unit .toMillis (timeout ));
391+ cachedTimeThread .join (unit .toMillis (timeout ));
375392 return result ;
376393 }
377394
@@ -471,29 +488,50 @@ public String toString() {
471488 }
472489 }
473490
474- static class EstimatedTimeThread extends Thread {
491+ /**
492+ * A thread to cache millisecond time values from
493+ * {@link System#nanoTime()} and {@link System#currentTimeMillis()}.
494+ *
495+ * The values are updated at a specified interval.
496+ */
497+ static class CachedTimeThread extends Thread {
475498
476499 final long interval ;
477500 final TimeCounter counter ;
478501 volatile boolean running = true ;
479- volatile long estimatedTimeInMillis ;
502+ volatile long relativeMillis ;
503+ volatile long absoluteMillis ;
480504
481- EstimatedTimeThread (String name , long interval ) {
505+ CachedTimeThread (String name , long interval ) {
482506 super (name );
483507 this .interval = interval ;
484- this .estimatedTimeInMillis = TimeValue .nsecToMSec (System .nanoTime ());
508+ this .relativeMillis = TimeValue .nsecToMSec (System .nanoTime ());
509+ this .absoluteMillis = System .currentTimeMillis ();
485510 this .counter = new TimeCounter ();
486511 setDaemon (true );
487512 }
488513
489- public long estimatedTimeInMillis () {
490- return this .estimatedTimeInMillis ;
514+ /**
515+ * Return the current time used for relative calculations. This is
516+ * {@link System#nanoTime()} truncated to milliseconds.
517+ */
518+ long relativeTimeInMillis () {
519+ return relativeMillis ;
520+ }
521+
522+ /**
523+ * Return the current epoch time, used to find absolute time. This is
524+ * a cached version of {@link System#currentTimeMillis()}.
525+ */
526+ long absoluteTimeInMillis () {
527+ return absoluteMillis ;
491528 }
492529
493530 @ Override
494531 public void run () {
495532 while (running ) {
496- estimatedTimeInMillis = TimeValue .nsecToMSec (System .nanoTime ());
533+ relativeMillis = TimeValue .nsecToMSec (System .nanoTime ());
534+ absoluteMillis = System .currentTimeMillis ();
497535 try {
498536 Thread .sleep (interval );
499537 } catch (InterruptedException e ) {
@@ -512,7 +550,7 @@ public long addAndGet(long delta) {
512550
513551 @ Override
514552 public long get () {
515- return estimatedTimeInMillis ;
553+ return relativeMillis ;
516554 }
517555 }
518556 }
0 commit comments