public RunnableScheduledFuture<?> poll(long timeout, TimeUnit unit)
     throws InterruptedException {
   long nanos = unit.toNanos(timeout);
   final ReentrantLock lock = this.lock;
   lock.lockInterruptibly();
   try {
     for (; ; ) {
       RunnableScheduledFuture<?> first = queue[0];
       if (first == null) {
         if (nanos <= 0) return null;
         else nanos = available.awaitNanos(nanos);
       } else {
         long delay = first.getDelay(NANOSECONDS);
         if (delay <= 0) return finishPoll(first);
         if (nanos <= 0) return null;
         if (nanos < delay || leader != null) nanos = available.awaitNanos(nanos);
         else {
           Thread thisThread = Thread.currentThread();
           leader = thisThread;
           try {
             long timeLeft = available.awaitNanos(delay);
             nanos -= delay - timeLeft;
           } finally {
             if (leader == thisThread) leader = null;
           }
         }
       }
     }
   } finally {
     if (leader == null && queue[0] != null) available.signal();
     lock.unlock();
   }
 }
 public RunnableScheduledFuture<?> take() throws InterruptedException {
   final ReentrantLock lock = this.lock;
   lock.lockInterruptibly();
   try {
     for (; ; ) {
       RunnableScheduledFuture<?> first = queue[0];
       if (first == null) available.await();
       else {
         long delay = first.getDelay(NANOSECONDS);
         if (delay <= 0) return finishPoll(first);
         else if (leader != null) available.await();
         else {
           Thread thisThread = Thread.currentThread();
           leader = thisThread;
           try {
             available.awaitNanos(delay);
           } finally {
             if (leader == thisThread) leader = null;
           }
         }
       }
     }
   } finally {
     if (leader == null && queue[0] != null) available.signal();
     lock.unlock();
   }
 }
 /**
  * Main execution method for delayed or periodic tasks. If pool is shut down, rejects the task.
  * Otherwise adds task to queue and starts a thread, if necessary, to run it. (We cannot prestart
  * the thread to run the task because the task (probably) shouldn't be run yet,) If the pool is
  * shut down while the task is being added, cancel and remove it if required by state and
  * run-after-shutdown parameters.
  *
  * @param task the task
  */
 private void delayedExecute(RunnableScheduledFuture<?> task) {
   if (isShutdown()) reject(task);
   else {
     super.getQueue().add(task);
     if (isShutdown() && !canRunInCurrentRunState(task.isPeriodic()) && remove(task))
       task.cancel(false);
     else ensurePrestart();
   }
 }
 public RunnableScheduledFuture<?> poll() {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     RunnableScheduledFuture<?> first = queue[0];
     if (first == null || first.getDelay(NANOSECONDS) > 0) return null;
     else return finishPoll(first);
   } finally {
     lock.unlock();
   }
 }
 /** Sift element added at top down to its heap-ordered spot. Call only when holding lock. */
 private void siftDown(int k, RunnableScheduledFuture<?> key) {
   int half = size >>> 1;
   while (k < half) {
     int child = (k << 1) + 1;
     RunnableScheduledFuture<?> c = queue[child];
     int right = child + 1;
     if (right < size && c.compareTo(queue[right]) > 0) c = queue[child = right];
     if (key.compareTo(c) <= 0) break;
     queue[k] = c;
     setIndex(c, k);
     k = child;
   }
   queue[k] = key;
   setIndex(key, k);
 }
 /**
  * Requeues a periodic task unless current run state precludes it. Same idea as delayedExecute
  * except drops task rather than rejecting.
  *
  * @param task the task
  */
 void reExecutePeriodic(RunnableScheduledFuture<?> task) {
   if (canRunInCurrentRunState(true)) {
     super.getQueue().add(task);
     if (!canRunInCurrentRunState(true) && remove(task)) task.cancel(false);
     else ensurePrestart();
   }
 }
 /** Sift element added at bottom up to its heap-ordered spot. Call only when holding lock. */
 private void siftUp(int k, RunnableScheduledFuture<?> key) {
   while (k > 0) {
     int parent = (k - 1) >>> 1;
     RunnableScheduledFuture<?> e = queue[parent];
     if (key.compareTo(e) >= 0) break;
     queue[k] = e;
     setIndex(e, k);
     k = parent;
   }
   queue[k] = key;
   setIndex(key, k);
 }
 /**
  * Cancels and clears the queue of all tasks that should not be run due to shutdown policy.
  * Invoked within super.shutdown.
  */
 @Override
 void onShutdown() {
   BlockingQueue<Runnable> q = super.getQueue();
   boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy();
   boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy();
   if (!keepDelayed && !keepPeriodic) {
     for (Object e : q.toArray())
       if (e instanceof RunnableScheduledFuture<?>) ((RunnableScheduledFuture<?>) e).cancel(false);
     q.clear();
   } else {
     // Traverse snapshot to avoid iterator exceptions
     for (Object e : q.toArray()) {
       if (e instanceof RunnableScheduledFuture) {
         RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>) e;
         if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed)
             || t.isCancelled()) { // also remove if already cancelled
           if (q.remove(t)) t.cancel(false);
         }
       }
     }
   }
   tryTerminate();
 }
 /**
  * Return first element only if it is expired. Used only by drainTo. Call only when holding
  * lock.
  */
 private RunnableScheduledFuture<?> peekExpired() {
   // assert lock.isHeldByCurrentThread();
   RunnableScheduledFuture<?> first = queue[0];
   return (first == null || first.getDelay(NANOSECONDS) > 0) ? null : first;
 }