/** Sequence number to break ties FIFO */ privatefinallong sequenceNumber;
/** The time the task is enabled to execute in nanoTime units */ privatelong time;
/** * Period in nanoseconds for repeating tasks. A positive * value indicates fixed-rate execution. A negative value * indicates fixed-delay execution. A value of 0 indicates a * non-repeating task. */ privatefinallong period;
/** The actual task to be re-enqueued by reExecutePeriodic */ RunnableScheduledFuture<V> outerTask = this;
/** * Index into delay queue, to support faster cancellation. * 因为堆实际就是一个完全二叉树,因此完全可以用数组来实现,因此这个heapIndex我在一开始的时候 * 认为它就是元素在数组的下标 */ int heapIndex;
/** * Creates a one-shot action with given nanoTime-based trigger time. */ ScheduledFutureTask(Runnable r, V result, long ns) { super(r, result); this.time = ns; this.period = 0; this.sequenceNumber = sequencer.getAndIncrement(); }
/** * Creates a periodic action with given nano time and period. */ ScheduledFutureTask(Runnable r, V result, long ns, long period) { super(r, result); this.time = ns; this.period = period; this.sequenceNumber = sequencer.getAndIncrement(); }
/** * Creates a one-shot action with given nanoTime-based trigger time. */ ScheduledFutureTask(Callable<V> callable, long ns) { super(callable); this.time = ns; this.period = 0; this.sequenceNumber = sequencer.getAndIncrement(); }
// 优先队列需要比较元素的优先关系(即大小),因此是定时任务,肯定是最近要执行的任务优先级越大 publicintcompareTo(Delayed other){ if (other == this) // compare zero if same object return0; if (other instanceof ScheduledFutureTask) { ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other; long diff = time - x.time; if (diff < 0) return -1; elseif (diff > 0) return1; elseif (sequenceNumber < x.sequenceNumber) return -1; else return1; } long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS); return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; }
/** * Returns {@code true} if this is a periodic (not a one-shot) action. * * @return {@code true} if periodic */ publicbooleanisPeriodic(){ return period != 0; }
/** * Sets the next time to run for a periodic task. */ privatevoidsetNextRunTime(){ long p = period; if (p > 0) time += p; else time = triggerTime(-p); }
Thread designated to wait for the task at the head of the queue. This variant of the Leader-Follower pattern (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to minimize unnecessary timed waiting. When a thread becomes the leader, it waits only for the next delay to elapse, but other threads await indefinitely. The leader thread must signal some other thread before returning from take() or poll(…), unless some other thread becomes leader in the interim. Whenever the head of the queue is replaced with a task with an earlier expiration time, the leader field is invalidated by being reset to null, and some waiting thread, but not necessarily the current leader, is signalled. So waiting threads must be prepared to acquire and lose leadership while waiting.