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