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