1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent; 8edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 9a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport static java.util.concurrent.TimeUnit.NANOSECONDS; 10e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 11e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.AbstractQueue; 12e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.Collection; 13e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.Iterator; 14e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.NoSuchElementException; 15e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.PriorityQueue; 16a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport java.util.concurrent.locks.Condition; 17a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport java.util.concurrent.locks.ReentrantLock; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed link to collections framework docs 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 24bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * An unbounded {@linkplain BlockingQueue blocking queue} of 2591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code Delayed} elements, in which an element can only be taken 26bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * when its delay has expired. The <em>head</em> of the queue is that 2791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code Delayed} element whose delay expired furthest in the 2891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * past. If no delay has expired there is no head and {@code poll} 2991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * will return {@code null}. Expiration occurs when an element's 3091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code getDelay(TimeUnit.NANOSECONDS)} method returns a value less 31bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * than or equal to zero. Even though unexpired elements cannot be 3291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * removed using {@code take} or {@code poll}, they are otherwise 3391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * treated as normal elements. For example, the {@code size} method 34bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * returns the count of both expired and unexpired elements. 35bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * This queue does not permit null elements. 36bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 37bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>This class and its iterator implement all of the 38bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <em>optional</em> methods of the {@link Collection} and {@link 39a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Iterator} interfaces. The Iterator provided in method {@link 40a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * #iterator()} is <em>not</em> guaranteed to traverse the elements of 41a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * the DelayQueue in any particular order. 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 45e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param <E> the type of elements held in this queue 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class DelayQueue<E extends Delayed> extends AbstractQueue<E> 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implements BlockingQueue<E> { 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 5091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle private final transient ReentrantLock lock = new ReentrantLock(); 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final PriorityQueue<E> q = new PriorityQueue<E>(); 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 54bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Thread designated to wait for the element at the head of 55bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the queue. This variant of the Leader-Follower pattern 56bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to 57bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * minimize unnecessary timed waiting. When a thread becomes 58bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the leader, it waits only for the next delay to elapse, but 59bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * other threads await indefinitely. The leader thread must 60bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * signal some other thread before returning from take() or 61bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * poll(...), unless some other thread becomes leader in the 62bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * interim. Whenever the head of the queue is replaced with 63bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * an element with an earlier expiration time, the leader 64bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * field is invalidated by being reset to null, and some 65bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * waiting thread, but not necessarily the current leader, is 66bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * signalled. So waiting threads must be prepared to acquire 67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * and lose leadership while waiting. 68bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 69edf43d27e240d82106f39ae91404963c23987234Narayan Kamath private Thread leader; 70bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 71bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 72bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Condition signalled when a newer element becomes available 73bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * at the head of the queue or a new thread may need to 74bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * become leader. 75bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 76bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private final Condition available = lock.newCondition(); 77bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 7991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Creates a new {@code DelayQueue} that is initially empty. 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DelayQueue() {} 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 8491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Creates a {@code DelayQueue} initially containing the elements of the 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * given collection of {@link Delayed} instances. 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 87bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param c the collection of elements to initially contain 88bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified collection or any 89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * of its elements are null 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DelayQueue(Collection<? extends E> c) { 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.addAll(c); 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Inserts the specified element into this delay queue. 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 98bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 9991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} (as specified by {@link Collection#add}) 100bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified element is null 101bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 102bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public boolean add(E e) { 103bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return offer(e); 104bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 105bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 106bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 107bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Inserts the specified element into this delay queue. 108bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 109bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 11091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} 111bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified element is null 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 113bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public boolean offer(E e) { 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 117bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson q.offer(e); 118bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (q.peek() == e) { 119bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = null; 120bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.signal(); 121bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 129bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Inserts the specified element into this delay queue. As the queue is 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unbounded this method will never block. 131bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 132bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 133bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 135bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public void put(E e) { 136bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson offer(e); 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Inserts the specified element into this delay queue. As the queue is 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unbounded this method will never block. 142bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 143bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout This parameter is ignored as the method never blocks 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unit This parameter is ignored as the method never blocks 14691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} 147bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 149bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public boolean offer(E e, long timeout, TimeUnit unit) { 150bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return offer(e); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 15491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Retrieves and removes the head of this queue, or returns {@code null} 155bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * if this queue has no elements with an expired delay. 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 15791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return the head of this queue, or {@code null} if this 158bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * queue has no elements with an expired delay 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 160bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public E poll() { 161bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson final ReentrantLock lock = this.lock; 162bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lock.lock(); 163bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson try { 164bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson E first = q.peek(); 165e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return (first == null || first.getDelay(NANOSECONDS) > 0) 166e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ? null 167e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak : q.poll(); 168bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } finally { 169bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lock.unlock(); 170bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 173bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 174bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Retrieves and removes the head of this queue, waiting if necessary 175bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * until an element with an expired delay is available on this queue. 176bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 177bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return the head of this queue 178bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws InterruptedException {@inheritDoc} 179bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public E take() throws InterruptedException { 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lockInterruptibly(); 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project E first = q.peek(); 186bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (first == null) 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project available.await(); 188bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson else { 189a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson long delay = first.getDelay(NANOSECONDS); 190e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (delay <= 0L) 191bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return q.poll(); 19291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle first = null; // don't retain ref while waiting 19391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (leader != null) 194bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.await(); 195bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson else { 196bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Thread thisThread = Thread.currentThread(); 197bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = thisThread; 198bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson try { 199bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.awaitNanos(delay); 200bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } finally { 201bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == thisThread) 202bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = null; 203bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 208bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == null && q.peek() != null) 209bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.signal(); 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 214bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 215bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Retrieves and removes the head of this queue, waiting if necessary 216bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * until an element with an expired delay is available on this queue, 217bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * or the specified wait time expires. 218bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 21991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return the head of this queue, or {@code null} if the 220bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * specified waiting time elapses before an element with 221bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * an expired delay becomes available 222bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws InterruptedException {@inheritDoc} 223bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 224bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public E poll(long timeout, TimeUnit unit) throws InterruptedException { 225bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson long nanos = unit.toNanos(timeout); 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lockInterruptibly(); 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project E first = q.peek(); 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (first == null) { 232e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (nanos <= 0L) 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nanos = available.awaitNanos(nanos); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 237a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson long delay = first.getDelay(NANOSECONDS); 238e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (delay <= 0L) 239bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return q.poll(); 240e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak if (nanos <= 0L) 241bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return null; 24291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle first = null; // don't retain ref while waiting 243bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (nanos < delay || leader != null) 244bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson nanos = available.awaitNanos(nanos); 245bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson else { 246bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Thread thisThread = Thread.currentThread(); 247bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = thisThread; 248bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson try { 249bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson long timeLeft = available.awaitNanos(delay); 250bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson nanos -= delay - timeLeft; 251bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } finally { 252bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == thisThread) 253bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = null; 254bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 259bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == null && q.peek() != null) 260bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.signal(); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 265bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 266bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Retrieves, but does not remove, the head of this queue, or 26791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * returns {@code null} if this queue is empty. Unlike 26891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code poll}, if no expired elements are available in the queue, 269bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * this method returns the element that will expire next, 270bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * if one exists. 271bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 27291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return the head of this queue, or {@code null} if this 27391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * queue is empty 274bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public E peek() { 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.peek(); 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.size(); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 295bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 29691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Returns first element only if it is expired. 297a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Used only by drainTo. Call only when holding lock. 298a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 299a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private E peekExpired() { 300a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson // assert lock.isHeldByCurrentThread(); 301a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson E first = q.peek(); 302a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson return (first == null || first.getDelay(NANOSECONDS) > 0) ? 303a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson null : first; 304a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 305a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 306a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 307bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws UnsupportedOperationException {@inheritDoc} 308bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws ClassCastException {@inheritDoc} 309bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 310bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws IllegalArgumentException {@inheritDoc} 311bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int drainTo(Collection<? super E> c) { 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == null) 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == this) 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int n = 0; 321a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (E e; (e = peekExpired()) != null;) { 322a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson c.add(e); // In this order, in case add() throws. 323a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson q.poll(); 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++n; 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return n; 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 332bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 333bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws UnsupportedOperationException {@inheritDoc} 334bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws ClassCastException {@inheritDoc} 335bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 336bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws IllegalArgumentException {@inheritDoc} 337bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int drainTo(Collection<? super E> c, int maxElements) { 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == null) 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == this) 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (maxElements <= 0) 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int n = 0; 349a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (E e; n < maxElements && (e = peekExpired()) != null;) { 350a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson c.add(e); // In this order, in case add() throws. 351a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson q.poll(); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++n; 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return n; 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically removes all of the elements from this delay queue. 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The queue will be empty after this call returns. 363bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Elements with an unexpired delay are not waited for; they are 364bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * simply discarded from the queue. 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project q.clear(); 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 37791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Always returns {@code Integer.MAX_VALUE} because 37891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * a {@code DelayQueue} is not capacity constrained. 379bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 38091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code Integer.MAX_VALUE} 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int remainingCapacity() { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Integer.MAX_VALUE; 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 386bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 387bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns an array containing all of the elements in this queue. 388bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The returned array elements are in no particular order. 389bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 390bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>The returned array will be "safe" in that no references to it are 391bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * maintained by this queue. (In other words, this method must allocate 392bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * a new array). The caller is thus free to modify the returned array. 393bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 394bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>This method acts as bridge between array-based and collection-based 395bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * APIs. 396bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 397bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return an array containing all of the elements in this queue 398bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object[] toArray() { 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.toArray(); 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 409bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 410bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns an array containing all of the elements in this queue; the 411bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * runtime type of the returned array is that of the specified array. 412bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The returned array elements are in no particular order. 413bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * If the queue fits in the specified array, it is returned therein. 414bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Otherwise, a new array is allocated with the runtime type of the 415bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * specified array and the size of this queue. 416bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 417bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If this queue fits in the specified array with room to spare 418bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * (i.e., the array has more elements than this queue), the element in 419bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the array immediately following the end of the queue is set to 42091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code null}. 421bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 422bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Like the {@link #toArray()} method, this method acts as bridge between 423bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * array-based and collection-based APIs. Further, this method allows 424bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * precise control over the runtime type of the output array, and may, 425bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * under certain circumstances, be used to save allocation costs. 426bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 427bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>The following code can be used to dump a delay queue into a newly 42891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * allocated array of {@code Delayed}: 429bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 430a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * <pre> {@code Delayed[] a = q.toArray(new Delayed[0]);}</pre> 431bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 43291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Note that {@code toArray(new Object[0])} is identical in function to 43391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code toArray()}. 434bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 435bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param a the array into which the elements of the queue are to 436bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * be stored, if it is big enough; otherwise, a new array of the 437bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * same runtime type is allocated for this purpose 438bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return an array containing all of the elements in this queue 439bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws ArrayStoreException if the runtime type of the specified array 440bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * is not a supertype of the runtime type of every element in 441bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * this queue 442bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified array is null 443bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 444bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public <T> T[] toArray(T[] a) { 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 448bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return q.toArray(a); 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 454bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 455bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Removes a single instance of the specified element from this 456bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * queue, if it is present, whether or not it has expired. 457bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean remove(Object o) { 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.remove(o); 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 469e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Identity-based version for use in Itr.remove. 470a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 471a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson void removeEQ(Object o) { 472a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson final ReentrantLock lock = this.lock; 473a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson lock.lock(); 474a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 475a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (Iterator<E> it = q.iterator(); it.hasNext(); ) { 476a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson if (o == it.next()) { 477a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson it.remove(); 478a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson break; 479a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 480a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 481a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } finally { 482a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson lock.unlock(); 483a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 484a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 485a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 486a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 487bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns an iterator over all the elements (both expired and 488bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * unexpired) in this queue. The iterator does not return the 4898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * elements in any particular order. 4908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 491e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <p>The returned iterator is 492e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 494bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return an iterator over the elements in this queue 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<E> iterator() { 497bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return new Itr(toArray()); 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 500bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 501bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Snapshot iterator that works off copy of underlying q array. 502bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 503bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private class Itr implements Iterator<E> { 504bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson final Object[] array; // Array of all elements 505a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson int cursor; // index of next element to return 506bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson int lastRet; // index of last element, or -1 if no such 507bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 508bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Itr(Object[] array) { 509bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lastRet = -1; 510bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson this.array = array; 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasNext() { 514bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return cursor < array.length; 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 517bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson @SuppressWarnings("unchecked") 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public E next() { 519bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (cursor >= array.length) 520bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throw new NoSuchElementException(); 521bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lastRet = cursor; 522bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return (E)array[cursor++]; 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove() { 526bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (lastRet < 0) 527bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throw new IllegalStateException(); 528a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson removeEQ(array[lastRet]); 529bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lastRet = -1; 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 534