/** 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);
 }
 /** 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);
 }