131 |
|
*/ |
132 |
|
private static final AtomicLong sequencer = new AtomicLong(0); |
133 |
|
|
134 |
+ |
|
135 |
+ |
/** |
136 |
+ |
* Value of System.nanoTime upon static initialization. This is |
137 |
+ |
* used as an offset by now() to avoid wraparound of time values |
138 |
+ |
* that would make them appear negative. |
139 |
+ |
*/ |
140 |
+ |
static final long initialNanoTime = System.nanoTime(); |
141 |
+ |
|
142 |
|
/** |
143 |
|
* Returns current nanosecond time. |
144 |
|
*/ |
145 |
< |
final long now() { |
146 |
< |
return System.nanoTime(); |
145 |
> |
static long now() { |
146 |
> |
return System.nanoTime() - initialNanoTime; |
147 |
|
} |
148 |
|
|
149 |
|
private class ScheduledFutureTask<V> |
202 |
|
} |
203 |
|
|
204 |
|
public long getDelay(TimeUnit unit) { |
205 |
< |
long d = unit.convert(time - now(), TimeUnit.NANOSECONDS); |
206 |
< |
return d; |
205 |
> |
long d = time - now(); |
206 |
> |
return d<=0? 0 : unit.convert(d, TimeUnit.NANOSECONDS); |
207 |
|
} |
208 |
|
|
209 |
|
public int compareTo(Delayed other) { |
452 |
|
} |
453 |
|
|
454 |
|
/** |
455 |
+ |
* Returns the trigger time of a delayed action |
456 |
+ |
*/ |
457 |
+ |
private static long nextTriggerTime(long delay, TimeUnit unit) { |
458 |
+ |
long triggerTime; |
459 |
+ |
long now = now(); |
460 |
+ |
if (delay <= 0) |
461 |
+ |
return now; // avoid negative trigger times |
462 |
+ |
else if ((triggerTime = now + unit.toNanos(delay)) < 0) |
463 |
+ |
return Long.MAX_VALUE; // avoid numerical overflow |
464 |
+ |
else |
465 |
+ |
return triggerTime; |
466 |
+ |
} |
467 |
+ |
|
468 |
+ |
/** |
469 |
|
* @throws RejectedExecutionException {@inheritDoc} |
470 |
|
* @throws NullPointerException {@inheritDoc} |
471 |
|
*/ |
474 |
|
TimeUnit unit) { |
475 |
|
if (command == null || unit == null) |
476 |
|
throw new NullPointerException(); |
477 |
< |
if (delay < 0) delay = 0; |
456 |
< |
long triggerTime = now() + unit.toNanos(delay); |
477 |
> |
long triggerTime = nextTriggerTime(delay, unit); |
478 |
|
RunnableScheduledFuture<?> t = decorateTask(command, |
479 |
|
new ScheduledFutureTask<Void>(command, null, triggerTime)); |
480 |
|
delayedExecute(t); |
481 |
|
return t; |
482 |
|
} |
483 |
< |
|
483 |
> |
|
484 |
|
/** |
485 |
|
* @throws RejectedExecutionException {@inheritDoc} |
486 |
|
* @throws NullPointerException {@inheritDoc} |
490 |
|
TimeUnit unit) { |
491 |
|
if (callable == null || unit == null) |
492 |
|
throw new NullPointerException(); |
493 |
< |
if (delay < 0) delay = 0; |
473 |
< |
long triggerTime = now() + unit.toNanos(delay); |
493 |
> |
long triggerTime = nextTriggerTime(delay, unit); |
494 |
|
RunnableScheduledFuture<V> t = decorateTask(callable, |
495 |
|
new ScheduledFutureTask<V>(callable, triggerTime)); |
496 |
|
delayedExecute(t); |
511 |
|
if (period <= 0) |
512 |
|
throw new IllegalArgumentException(); |
513 |
|
if (initialDelay < 0) initialDelay = 0; |
514 |
< |
long triggerTime = now() + unit.toNanos(initialDelay); |
514 |
> |
long triggerTime = nextTriggerTime(initialDelay, unit); |
515 |
|
ScheduledFutureTask<Void> sft = |
516 |
|
new ScheduledFutureTask<Void>(command, |
517 |
|
null, |
536 |
|
throw new NullPointerException(); |
537 |
|
if (delay <= 0) |
538 |
|
throw new IllegalArgumentException(); |
539 |
< |
if (initialDelay < 0) initialDelay = 0; |
520 |
< |
long triggerTime = now() + unit.toNanos(initialDelay); |
539 |
> |
long triggerTime = nextTriggerTime(initialDelay, unit); |
540 |
|
ScheduledFutureTask<Void> sft = |
541 |
|
new ScheduledFutureTask<Void>(command, |
542 |
|
null, |