1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is free software; you can redistribute it and/or modify it 529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * under the terms of the GNU General Public License version 2 only, as 629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * published by the Free Software Foundation. Oracle designates this 729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * particular file as subject to the "Classpath" exception as provided 829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * by Oracle in the LICENSE file that accompanied this code. 929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 1029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is distributed in the hope that it will be useful, but WITHOUT 1129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * version 2 for more details (a copy is included in the LICENSE file that 1429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * accompanied this code). 1529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 1629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * You should have received a copy of the GNU General Public License version 1729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 2 along with this work; if not, write to the Free Software Foundation, 1829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 2029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * or visit www.oracle.com if you need additional information or have any 2229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * questions. 2329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer */ 2429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer 2529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer/* 2629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This file is available under and governed by the GNU General Public 2729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * License version 2 only, as published by the Free Software Foundation. 2829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * However, the following notice accompanied the original version of this 2929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * file: 3029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 33a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent; 37edf43d27e240d82106f39ae91404963c23987234Narayan Kamath 38a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport static java.util.concurrent.TimeUnit.NANOSECONDS; 39b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak 40b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.AbstractQueue; 41b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Collection; 42b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.Iterator; 43b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.NoSuchElementException; 44b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.PriorityQueue; 45a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport java.util.concurrent.locks.Condition; 46a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport java.util.concurrent.locks.ReentrantLock; 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed link to collections framework docs 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 53bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * An unbounded {@linkplain BlockingQueue blocking queue} of 5491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code Delayed} elements, in which an element can only be taken 55bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * when its delay has expired. The <em>head</em> of the queue is that 5691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code Delayed} element whose delay expired furthest in the 5791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * past. If no delay has expired there is no head and {@code poll} 5891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * will return {@code null}. Expiration occurs when an element's 5991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code getDelay(TimeUnit.NANOSECONDS)} method returns a value less 60bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * than or equal to zero. Even though unexpired elements cannot be 6191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * removed using {@code take} or {@code poll}, they are otherwise 6291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * treated as normal elements. For example, the {@code size} method 63bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * returns the count of both expired and unexpired elements. 64bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * This queue does not permit null elements. 65bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 66bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>This class and its iterator implement all of the 67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <em>optional</em> methods of the {@link Collection} and {@link 68a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Iterator} interfaces. The Iterator provided in method {@link 69a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * #iterator()} is <em>not</em> guaranteed to traverse the elements of 70a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * the DelayQueue in any particular order. 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 74b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * @param <E> the type of elements held in this queue 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class DelayQueue<E extends Delayed> extends AbstractQueue<E> 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implements BlockingQueue<E> { 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle private final transient ReentrantLock lock = new ReentrantLock(); 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final PriorityQueue<E> q = new PriorityQueue<E>(); 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 83bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Thread designated to wait for the element at the head of 84bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the queue. This variant of the Leader-Follower pattern 85bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to 86bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * minimize unnecessary timed waiting. When a thread becomes 87bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the leader, it waits only for the next delay to elapse, but 88bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * other threads await indefinitely. The leader thread must 89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * signal some other thread before returning from take() or 90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * poll(...), unless some other thread becomes leader in the 91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * interim. Whenever the head of the queue is replaced with 92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * an element with an earlier expiration time, the leader 93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * field is invalidated by being reset to null, and some 94bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * waiting thread, but not necessarily the current leader, is 95bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * signalled. So waiting threads must be prepared to acquire 96bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * and lose leadership while waiting. 97bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 98edf43d27e240d82106f39ae91404963c23987234Narayan Kamath private Thread leader; 99bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 100bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 101bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Condition signalled when a newer element becomes available 102bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * at the head of the queue or a new thread may need to 103bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * become leader. 104bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 105bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private final Condition available = lock.newCondition(); 106bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 107bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 10891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Creates a new {@code DelayQueue} that is initially empty. 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DelayQueue() {} 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 11391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Creates a {@code DelayQueue} initially containing the elements of the 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * given collection of {@link Delayed} instances. 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 116bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param c the collection of elements to initially contain 117bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified collection or any 118bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * of its elements are null 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DelayQueue(Collection<? extends E> c) { 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.addAll(c); 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Inserts the specified element into this delay queue. 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 127bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 12891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} (as specified by {@link Collection#add}) 129bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified element is null 130bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 131bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public boolean add(E e) { 132bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return offer(e); 133bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 134bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 135bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 136bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Inserts the specified element into this delay queue. 137bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 138bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 13991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} 140bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified element is null 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 142bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public boolean offer(E e) { 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 146bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson q.offer(e); 147bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (q.peek() == e) { 148bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = null; 149bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.signal(); 150bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 158bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Inserts the specified element into this delay queue. As the queue is 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unbounded this method will never block. 160bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 161bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 162bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 164bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public void put(E e) { 165bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson offer(e); 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Inserts the specified element into this delay queue. As the queue is 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unbounded this method will never block. 171bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 172bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param e the element to add 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout This parameter is ignored as the method never blocks 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unit This parameter is ignored as the method never blocks 17591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} 176bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 178bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public boolean offer(E e, long timeout, TimeUnit unit) { 179bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return offer(e); 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 18391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Retrieves and removes the head of this queue, or returns {@code null} 184bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * if this queue has no elements with an expired delay. 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 18691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return the head of this queue, or {@code null} if this 187bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * queue has no elements with an expired delay 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 189bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public E poll() { 190bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson final ReentrantLock lock = this.lock; 191bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lock.lock(); 192bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson try { 193bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson E first = q.peek(); 194b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak return (first == null || first.getDelay(NANOSECONDS) > 0) 195b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak ? null 196b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak : q.poll(); 197bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } finally { 198bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lock.unlock(); 199bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 202bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 203bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Retrieves and removes the head of this queue, waiting if necessary 204bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * until an element with an expired delay is available on this queue. 205bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 206bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return the head of this queue 207bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws InterruptedException {@inheritDoc} 208bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public E take() throws InterruptedException { 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lockInterruptibly(); 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project E first = q.peek(); 215bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (first == null) 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project available.await(); 217bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson else { 218a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson long delay = first.getDelay(NANOSECONDS); 219b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak if (delay <= 0L) 220bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return q.poll(); 22191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle first = null; // don't retain ref while waiting 22291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (leader != null) 223bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.await(); 224bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson else { 225bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Thread thisThread = Thread.currentThread(); 226bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = thisThread; 227bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson try { 228bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.awaitNanos(delay); 229bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } finally { 230bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == thisThread) 231bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = null; 232bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 237bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == null && q.peek() != null) 238bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.signal(); 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 243bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 244bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Retrieves and removes the head of this queue, waiting if necessary 245bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * until an element with an expired delay is available on this queue, 246bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * or the specified wait time expires. 247bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 24891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return the head of this queue, or {@code null} if the 249bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * specified waiting time elapses before an element with 250bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * an expired delay becomes available 251bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws InterruptedException {@inheritDoc} 252bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 253bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public E poll(long timeout, TimeUnit unit) throws InterruptedException { 254bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson long nanos = unit.toNanos(timeout); 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lockInterruptibly(); 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project E first = q.peek(); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (first == null) { 261b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak if (nanos <= 0L) 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nanos = available.awaitNanos(nanos); 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 266a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson long delay = first.getDelay(NANOSECONDS); 267b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak if (delay <= 0L) 268bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return q.poll(); 269b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak if (nanos <= 0L) 270bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return null; 27191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle first = null; // don't retain ref while waiting 272bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (nanos < delay || leader != null) 273bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson nanos = available.awaitNanos(nanos); 274bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson else { 275bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Thread thisThread = Thread.currentThread(); 276bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = thisThread; 277bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson try { 278bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson long timeLeft = available.awaitNanos(delay); 279bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson nanos -= delay - timeLeft; 280bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } finally { 281bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == thisThread) 282bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson leader = null; 283bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 288bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (leader == null && q.peek() != null) 289bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson available.signal(); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 294bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 295bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Retrieves, but does not remove, the head of this queue, or 29691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * returns {@code null} if this queue is empty. Unlike 29791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code poll}, if no expired elements are available in the queue, 298bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * this method returns the element that will expire next, 299bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * if one exists. 300bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 30191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return the head of this queue, or {@code null} if this 30291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * queue is empty 303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public E peek() { 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.peek(); 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int size() { 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.size(); 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 324bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 32591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Returns first element only if it is expired. 326a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Used only by drainTo. Call only when holding lock. 327a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 328a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private E peekExpired() { 329a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson // assert lock.isHeldByCurrentThread(); 330a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson E first = q.peek(); 331a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson return (first == null || first.getDelay(NANOSECONDS) > 0) ? 332a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson null : first; 333a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 334a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 335a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 336bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws UnsupportedOperationException {@inheritDoc} 337bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws ClassCastException {@inheritDoc} 338bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 339bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws IllegalArgumentException {@inheritDoc} 340bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int drainTo(Collection<? super E> c) { 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == null) 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == this) 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int n = 0; 350a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (E e; (e = peekExpired()) != null;) { 351a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson c.add(e); // In this order, in case add() throws. 352a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson q.poll(); 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++n; 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return n; 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 361bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 362bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws UnsupportedOperationException {@inheritDoc} 363bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws ClassCastException {@inheritDoc} 364bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException {@inheritDoc} 365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws IllegalArgumentException {@inheritDoc} 366bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int drainTo(Collection<? super E> c, int maxElements) { 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == null) 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (c == this) 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (maxElements <= 0) 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int n = 0; 378a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (E e; n < maxElements && (e = peekExpired()) != null;) { 379a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson c.add(e); // In this order, in case add() throws. 380a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson q.poll(); 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ++n; 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return n; 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically removes all of the elements from this delay queue. 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The queue will be empty after this call returns. 392bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Elements with an unexpired delay are not waited for; they are 393bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * simply discarded from the queue. 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() { 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project q.clear(); 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 40691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Always returns {@code Integer.MAX_VALUE} because 40791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * a {@code DelayQueue} is not capacity constrained. 408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 40991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code Integer.MAX_VALUE} 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int remainingCapacity() { 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Integer.MAX_VALUE; 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 415bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 416bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns an array containing all of the elements in this queue. 417bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The returned array elements are in no particular order. 418bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 419bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>The returned array will be "safe" in that no references to it are 420bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * maintained by this queue. (In other words, this method must allocate 421bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * a new array). The caller is thus free to modify the returned array. 422bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 423bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>This method acts as bridge between array-based and collection-based 424bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * APIs. 425bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 426bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return an array containing all of the elements in this queue 427bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object[] toArray() { 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.toArray(); 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 438bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 439bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns an array containing all of the elements in this queue; the 440bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * runtime type of the returned array is that of the specified array. 441bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The returned array elements are in no particular order. 442bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * If the queue fits in the specified array, it is returned therein. 443bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Otherwise, a new array is allocated with the runtime type of the 444bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * specified array and the size of this queue. 445bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 446bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If this queue fits in the specified array with room to spare 447bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * (i.e., the array has more elements than this queue), the element in 448bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the array immediately following the end of the queue is set to 44991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code null}. 450bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 451bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Like the {@link #toArray()} method, this method acts as bridge between 452bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * array-based and collection-based APIs. Further, this method allows 453bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * precise control over the runtime type of the output array, and may, 454bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * under certain circumstances, be used to save allocation costs. 455bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 456bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>The following code can be used to dump a delay queue into a newly 45791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * allocated array of {@code Delayed}: 458bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 459a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * <pre> {@code Delayed[] a = q.toArray(new Delayed[0]);}</pre> 460bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 46191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Note that {@code toArray(new Object[0])} is identical in function to 46291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code toArray()}. 463bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 464bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @param a the array into which the elements of the queue are to 465bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * be stored, if it is big enough; otherwise, a new array of the 466bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * same runtime type is allocated for this purpose 467bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return an array containing all of the elements in this queue 468bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws ArrayStoreException if the runtime type of the specified array 469bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * is not a supertype of the runtime type of every element in 470bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * this queue 471bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws NullPointerException if the specified array is null 472bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 473bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public <T> T[] toArray(T[] a) { 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 477bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return q.toArray(a); 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 483bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 484bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Removes a single instance of the specified element from this 485bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * queue, if it is present, whether or not it has expired. 486bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean remove(Object o) { 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return q.remove(o); 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 498b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * Identity-based version for use in Itr.remove. 499a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 500a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson void removeEQ(Object o) { 501a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson final ReentrantLock lock = this.lock; 502a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson lock.lock(); 503a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 504a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson for (Iterator<E> it = q.iterator(); it.hasNext(); ) { 505a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson if (o == it.next()) { 506a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson it.remove(); 507a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson break; 508a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 509a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 510a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } finally { 511a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson lock.unlock(); 512a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 513a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 514a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 515a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 516bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Returns an iterator over all the elements (both expired and 517bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * unexpired) in this queue. The iterator does not return the 5188eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * elements in any particular order. 5198eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * 520b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <p>The returned iterator is 521b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 523bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return an iterator over the elements in this queue 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Iterator<E> iterator() { 526bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return new Itr(toArray()); 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 529bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 530bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Snapshot iterator that works off copy of underlying q array. 531bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 532bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private class Itr implements Iterator<E> { 533bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson final Object[] array; // Array of all elements 534a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson int cursor; // index of next element to return 535bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson int lastRet; // index of last element, or -1 if no such 536bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 537bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Itr(Object[] array) { 538bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lastRet = -1; 539bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson this.array = array; 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasNext() { 543bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return cursor < array.length; 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 546bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson @SuppressWarnings("unchecked") 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public E next() { 548bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (cursor >= array.length) 549bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throw new NoSuchElementException(); 550bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lastRet = cursor; 551bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return (E)array[cursor++]; 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove() { 555bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (lastRet < 0) 556bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throw new IllegalStateException(); 557a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson removeEQ(array[lastRet]); 558bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson lastRet = -1; 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 563