@Override public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { ObjectUtil.checkNotNull(callable, "callable"); ObjectUtil.checkNotNull(unit, "unit"); if (delay < 0) { delay = 0; } validateScheduled0(delay, unit); return schedule(new ScheduledFutureTask<V>( this, callable, ScheduledFutureTask.deadlineNanos(unit.toNanos(delay)))); }
@Override public int compare(ScheduledFutureTask<?> o1, ScheduledFutureTask<?> o2) { return o1.compareTo(o2); } };
@Override public long getDelay(TimeUnit unit) { return unit.convert(delayNanos(), TimeUnit.NANOSECONDS); }
public long delayNanos() { return Math.max(0, deadlineNanos() - nanoTime()); }
@Override public void run() { assert executor().inEventLoop(); try { if (periodNanos == 0) { if (setUncancellableInternal()) { V result = task.call(); setSuccessInternal(result); if (!isCancelled()) { task.call(); if (!executor().isShutdown()) { long p = periodNanos; if (p > 0) { deadlineNanos += p; } else { deadlineNanos = nanoTime() - p; if (!isCancelled()) { ((AbstractScheduledEventExecutor) executor()).scheduledTaskQueue; assert scheduledTaskQueue != null; scheduledTaskQueue.add(this); setFailureInternal(cause);
static long deadlineNanos(long delay) { long deadlineNanos = nanoTime() + delay; // Guard against overflow return deadlineNanos < 0 ? Long.MAX_VALUE : deadlineNanos; }
public long delayNanos(long currentTimeNanos) { return Math.max(0, deadlineNanos() - (currentTimeNanos - START_TIME)); }
/** * {@inheritDoc} * * @param mayInterruptIfRunning this value has no effect in this implementation. */ @Override public boolean cancel(boolean mayInterruptIfRunning) { boolean canceled = super.cancel(mayInterruptIfRunning); if (canceled) { ((AbstractScheduledEventExecutor) executor()).removeScheduled(this); } return canceled; }
/** * Cancel all scheduled tasks. * * This method MUST be called only when {@link #inEventLoop()} is {@code true}. */ protected void cancelScheduledTasks() { assert inEventLoop(); PriorityQueue<ScheduledFutureTask<?>> scheduledTaskQueue = this.scheduledTaskQueue; if (isNullOrEmpty(scheduledTaskQueue)) { return; } final ScheduledFutureTask<?>[] scheduledTasks = scheduledTaskQueue.toArray(new ScheduledFutureTask<?>[0]); for (ScheduledFutureTask<?> task: scheduledTasks) { task.cancelWithoutRemove(false); } scheduledTaskQueue.clearIgnoringIndexes(); }
@Override public void run() { assert executor().inEventLoop(); try { if (periodNanos == 0) { if (setUncancellableInternal()) { V result = task.call(); setSuccessInternal(result); if (!isCancelled()) { task.call(); if (!executor().isShutdown()) { long p = periodNanos; if (p > 0) { deadlineNanos += p; } else { deadlineNanos = nanoTime() - p; if (!isCancelled()) { ((AbstractScheduledEventExecutor) executor()).scheduledTaskQueue; assert scheduledTaskQueue != null; scheduledTaskQueue.add(this); setFailureInternal(cause);
/** * Updates the internal timestamp that tells when a submitted task was executed most recently. * {@link #runAllTasks()} and {@link #runAllTasks(long)} updates this timestamp automatically, and thus there's * usually no need to call this method. However, if you take the tasks manually using {@link #takeTask()} or * {@link #pollTask()}, you have to call this method at the end of task execution loop for accurate quiet period * checks. */ protected void updateLastExecutionTime() { lastExecutionTime = ScheduledFutureTask.nanoTime(); }
public long delayNanos() { return Math.max(0, deadlineNanos() - nanoTime()); }
@Override public int compareTo(Delayed o) { if (this == o) { return 0; } ScheduledFutureTask<?> that = (ScheduledFutureTask<?>) o; long d = deadlineNanos() - that.deadlineNanos(); if (d < 0) { return -1; } else if (d > 0) { return 1; } else if (id < that.id) { return -1; } else if (id == that.id) { throw new Error(); } else { return 1; } }
/** * {@inheritDoc} * * @param mayInterruptIfRunning this value has no effect in this implementation. */ @Override public boolean cancel(boolean mayInterruptIfRunning) { boolean canceled = super.cancel(mayInterruptIfRunning); if (canceled) { ((AbstractScheduledEventExecutor) executor()).removeScheduled(this); } return canceled; }
/** * Cancel all scheduled tasks. * * This method MUST be called only when {@link #inEventLoop()} is {@code true}. */ protected void cancelScheduledTasks() { assert inEventLoop(); PriorityQueue<ScheduledFutureTask<?>> scheduledTaskQueue = this.scheduledTaskQueue; if (isNullOrEmpty(scheduledTaskQueue)) { return; } final ScheduledFutureTask<?>[] scheduledTasks = scheduledTaskQueue.toArray(new ScheduledFutureTask<?>[0]); for (ScheduledFutureTask<?> task: scheduledTasks) { task.cancelWithoutRemove(false); } scheduledTaskQueue.clearIgnoringIndexes(); }
@Override public void run() { assert executor().inEventLoop(); try { if (periodNanos == 0) { if (setUncancellableInternal()) { V result = task.call(); setSuccessInternal(result); if (!isCancelled()) { task.call(); if (!executor().isShutdown()) { long p = periodNanos; if (p > 0) { deadlineNanos += p; } else { deadlineNanos = nanoTime() - p; if (!isCancelled()) { ((AbstractScheduledEventExecutor) executor()).scheduledTaskQueue; assert scheduledTaskQueue != null; scheduledTaskQueue.add(this); setFailureInternal(cause);
@Override public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { ObjectUtil.checkNotNull(command, "command"); ObjectUtil.checkNotNull(unit, "unit"); if (delay < 0) { delay = 0; } validateScheduled0(delay, unit); return schedule(new ScheduledFutureTask<Void>( this, command, null, ScheduledFutureTask.deadlineNanos(unit.toNanos(delay)))); }
@Override public long getDelay(TimeUnit unit) { return unit.convert(delayNanos(), TimeUnit.NANOSECONDS); }
protected static long nanoTime() { return ScheduledFutureTask.nanoTime(); }
public long delayNanos() { return Math.max(0, deadlineNanos() - nanoTime()); }