示例#1
0
 /**
  * Retrieves and removes the head of this queue, waiting if necessary until an element with an
  * expired delay is available on this queue.
  *
  * @return the head of this queue
  * @throws InterruptedException {@inheritDoc}
  */
 public E take() throws InterruptedException {
   final ReentrantLock lock = this.lock;
   lock.lockInterruptibly();
   try {
     for (; ; ) {
       E first = q.peek();
       if (first == null) available.await();
       else {
         long delay = first.getDelay(TimeUnit.NANOSECONDS);
         if (delay <= 0) return q.poll();
         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 && q.peek() != null) available.signal();
     lock.unlock();
   }
 }
示例#2
0
 /**
  * Retrieves and removes the head of this queue, waiting if necessary until an element with an
  * expired delay is available on this queue, or the specified wait time expires.
  *
  * @return the head of this queue, or <tt>null</tt> if the specified waiting time elapses before
  *     an element with an expired delay becomes available
  * @throws InterruptedException {@inheritDoc}
  */
 public E poll(long timeout, TimeUnit unit) throws InterruptedException {
   long nanos = unit.toNanos(timeout);
   final ReentrantLock lock = this.lock;
   lock.lockInterruptibly();
   try {
     for (; ; ) {
       E first = q.peek();
       if (first == null) {
         if (nanos <= 0) return null;
         else nanos = available.awaitNanos(nanos);
       } else {
         long delay = first.getDelay(TimeUnit.NANOSECONDS);
         if (delay <= 0) return q.poll();
         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 && q.peek() != null) available.signal();
     lock.unlock();
   }
 }
示例#3
0
 /**
  * Retrieves and removes the head of this queue, waiting if necessary until an element with an
  * expired delay is available on this queue, or the specified wait time expires.
  *
  * @return the head of this queue, or <tt>null</tt> if the specified waiting time elapses before
  *     an element with an expired delay becomes available
  * @throws InterruptedException {@inheritDoc}
  */
 public E poll(long timeout, TimeUnit unit) throws InterruptedException {
   long nanos = unit.toNanos(timeout);
   final ReentrantLock lock = this.lock;
   lock.lockInterruptibly();
   try {
     for (; ; ) {
       E first = q.peek();
       if (first == null) {
         if (nanos <= 0) return null;
         else nanos = available.awaitNanos(nanos);
       } else {
         long delay = first.getDelay(TimeUnit.NANOSECONDS);
         if (delay > 0) {
           if (nanos <= 0) return null;
           if (delay > nanos) delay = nanos;
           long timeLeft = available.awaitNanos(delay);
           nanos -= delay - timeLeft;
         } else {
           E x = q.poll();
           assert x != null;
           if (q.size() != 0) available.signalAll();
           return x;
         }
       }
     }
   } finally {
     lock.unlock();
   }
 }
示例#4
0
 /**
  * Retrieves and removes the head of this queue, or returns <tt>null</tt> if this queue has no
  * elements with an expired delay.
  *
  * @return the head of this queue, or <tt>null</tt> if this queue has no elements with an expired
  *     delay
  */
 public E poll() {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     E first = q.peek();
     if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) return null;
     else return q.poll();
   } finally {
     lock.unlock();
   }
 }
示例#5
0
 /**
  * Inserts the specified element into this delay queue.
  *
  * @param e the element to add
  * @return <tt>true</tt>
  * @throws NullPointerException if the specified element is null
  */
 public boolean offer(E e) {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     E first = q.peek();
     q.offer(e);
     if (first == null || e.compareTo(first) < 0) available.signalAll();
     return true;
   } finally {
     lock.unlock();
   }
 }
示例#6
0
 /**
  * Inserts the specified element into this delay queue.
  *
  * @param e the element to add
  * @return <tt>true</tt>
  * @throws NullPointerException if the specified element is null
  */
 public boolean offer(E e) {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     q.offer(e);
     if (q.peek() == e) {
       leader = null;
       available.signal();
     }
     return true;
   } finally {
     lock.unlock();
   }
 }
示例#7
0
 /**
  * Retrieves and removes the head of this queue, or returns <tt>null</tt> if this queue has no
  * elements with an expired delay.
  *
  * @return the head of this queue, or <tt>null</tt> if this queue has no elements with an expired
  *     delay
  */
 public E poll() {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     E first = q.peek();
     if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) return null;
     else {
       E x = q.poll();
       assert x != null;
       if (q.size() != 0) available.signalAll();
       return x;
     }
   } finally {
     lock.unlock();
   }
 }
示例#8
0
 /**
  * Removes a single instance of the specified element from this queue, if it is present, whether
  * or not it has expired.
  */
 public boolean remove(Object o) {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     return q.remove(o);
   } finally {
     lock.unlock();
   }
 }
示例#9
0
 /**
  * Returns an array containing all of the elements in this queue; the runtime type of the returned
  * array is that of the specified array. The returned array elements are in no particular order.
  * If the queue fits in the specified array, it is returned therein. Otherwise, a new array is
  * allocated with the runtime type of the specified array and the size of this queue.
  *
  * <p>If this queue fits in the specified array with room to spare (i.e., the array has more
  * elements than this queue), the element in the array immediately following the end of the queue
  * is set to <tt>null</tt>.
  *
  * <p>Like the {@link #toArray()} method, this method acts as bridge between array-based and
  * collection-based APIs. Further, this method allows precise control over the runtime type of the
  * output array, and may, under certain circumstances, be used to save allocation costs.
  *
  * <p>The following code can be used to dump a delay queue into a newly allocated array of
  * <tt>Delayed</tt>:
  *
  * <pre>
  *     Delayed[] a = q.toArray(new Delayed[0]);</pre>
  *
  * Note that <tt>toArray(new Object[0])</tt> is identical in function to <tt>toArray()</tt>.
  *
  * @param a the array into which the elements of the queue are to be stored, if it is big enough;
  *     otherwise, a new array of the same runtime type is allocated for this purpose
  * @return an array containing all of the elements in this queue
  * @throws ArrayStoreException if the runtime type of the specified array is not a supertype of
  *     the runtime type of every element in this queue
  * @throws NullPointerException if the specified array is null
  */
 public <T> T[] toArray(T[] a) {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     return q.toArray(a);
   } finally {
     lock.unlock();
   }
 }
示例#10
0
 /**
  * Returns an array containing all of the elements in this queue. The returned array elements are
  * in no particular order.
  *
  * <p>The returned array will be "safe" in that no references to it are maintained by this queue.
  * (In other words, this method must allocate a new array). The caller is thus free to modify the
  * returned array.
  *
  * <p>This method acts as bridge between array-based and collection-based APIs.
  *
  * @return an array containing all of the elements in this queue
  */
 public Object[] toArray() {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     return q.toArray();
   } finally {
     lock.unlock();
   }
 }
示例#11
0
 /**
  * Atomically removes all of the elements from this delay queue. The queue will be empty after
  * this call returns. Elements with an unexpired delay are not waited for; they are simply
  * discarded from the queue.
  */
 public void clear() {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     q.clear();
   } finally {
     lock.unlock();
   }
 }
示例#12
0
 /**
  * @throws UnsupportedOperationException {@inheritDoc}
  * @throws ClassCastException {@inheritDoc}
  * @throws NullPointerException {@inheritDoc}
  * @throws IllegalArgumentException {@inheritDoc}
  */
 public int drainTo(Collection<? super E> c) {
   if (c == null) throw new NullPointerException();
   if (c == this) throw new IllegalArgumentException();
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     int n = 0;
     for (; ; ) {
       E first = q.peek();
       if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) break;
       c.add(q.poll());
       ++n;
     }
     return n;
   } finally {
     lock.unlock();
   }
 }
示例#13
0
 public int size() {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     return q.size();
   } finally {
     lock.unlock();
   }
 }
示例#14
0
 /**
  * Retrieves, but does not remove, the head of this queue, or returns <tt>null</tt> if this queue
  * is empty. Unlike <tt>poll</tt>, if no expired elements are available in the queue, this method
  * returns the element that will expire next, if one exists.
  *
  * @return the head of this queue, or <tt>null</tt> if this queue is empty.
  */
 public E peek() {
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     return q.peek();
   } finally {
     lock.unlock();
   }
 }
示例#15
0
 /**
  * @throws UnsupportedOperationException {@inheritDoc}
  * @throws ClassCastException {@inheritDoc}
  * @throws NullPointerException {@inheritDoc}
  * @throws IllegalArgumentException {@inheritDoc}
  */
 public int drainTo(Collection<? super E> c, int maxElements) {
   if (c == null) throw new NullPointerException();
   if (c == this) throw new IllegalArgumentException();
   if (maxElements <= 0) return 0;
   final ReentrantLock lock = this.lock;
   lock.lock();
   try {
     int n = 0;
     while (n < maxElements) {
       E first = q.peek();
       if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) break;
       c.add(q.poll());
       ++n;
     }
     if (n > 0) available.signalAll();
     return n;
   } finally {
     lock.unlock();
   }
 }
示例#16
0
 /**
  * Retrieves and removes the head of this queue, waiting if necessary until an element with an
  * expired delay is available on this queue.
  *
  * @return the head of this queue
  * @throws InterruptedException {@inheritDoc}
  */
 public E take() throws InterruptedException {
   final ReentrantLock lock = this.lock;
   lock.lockInterruptibly();
   try {
     for (; ; ) {
       E first = q.peek();
       if (first == null) {
         available.await();
       } else {
         long delay = first.getDelay(TimeUnit.NANOSECONDS);
         if (delay > 0) {
           long tl = available.awaitNanos(delay);
         } else {
           E x = q.poll();
           assert x != null;
           if (q.size() != 0) available.signalAll(); // wake up other takers
           return x;
         }
       }
     }
   } finally {
     lock.unlock();
   }
 }