ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/PriorityBlockingQueue.java
Revision: 1.23
Committed: Sat Sep 13 18:51:11 2003 UTC (20 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.22: +8 -6 lines
Log Message:
Proofreading pass -- many minor adjustments

File Contents

# User Rev Content
1 dl 1.2 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain. Use, modify, and
4     * redistribute this code in any way without acknowledgement.
5     */
6    
7 tim 1.1 package java.util.concurrent;
8 tim 1.13
9 dl 1.8 import java.util.concurrent.locks.*;
10 tim 1.1 import java.util.*;
11    
12     /**
13 dholmes 1.16 * An unbounded {@linkplain BlockingQueue blocking queue} based on a
14     * {@link PriorityQueue},
15     * obeying its ordering rules and implementation characteristics.
16     * While this queue is logically unbounded,
17 dl 1.15 * attempted additions may fail due to resource exhaustion (causing
18 dholmes 1.16 * <tt>OutOfMemoryError</tt>).
19 dl 1.20 *
20 dl 1.23 * <p>This class implements all of the <em>optional</em> methods
21     * of the {@link Collection} and {@link Iterator} interfaces.
22 dl 1.20 * <p>The Iterator provided in method {@link #iterator()} is
23     * <em>not</em> guaranteed to traverse the elements of the
24     * PriorityBlockingQueue in any particular order. If you need ordered
25     * traversal, consider using <tt>Arrays.sort(pq.toArray())</tt>.
26     *
27 dl 1.6 * @since 1.5
28     * @author Doug Lea
29 dholmes 1.14 */
30 dl 1.5 public class PriorityBlockingQueue<E> extends AbstractQueue<E>
31 dl 1.15 implements BlockingQueue<E>, java.io.Serializable {
32 dl 1.21 private static final long serialVersionUID = 5595510919245408276L;
33 tim 1.1
34 dl 1.5 private final PriorityQueue<E> q;
35 dl 1.9 private final ReentrantLock lock = new ReentrantLock(true);
36 dl 1.5 private final Condition notEmpty = lock.newCondition();
37    
38 dl 1.2 /**
39 dholmes 1.16 * Creates a <tt>PriorityBlockingQueue</tt> with the default initial
40 dholmes 1.14 * capacity
41 dholmes 1.10 * (11) that orders its elements according to their natural
42 tim 1.18 * ordering (using <tt>Comparable</tt>).
43 dl 1.2 */
44     public PriorityBlockingQueue() {
45 dl 1.5 q = new PriorityQueue<E>();
46 dl 1.2 }
47    
48     /**
49 dholmes 1.16 * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
50 dholmes 1.10 * capacity
51     * that orders its elements according to their natural ordering
52 tim 1.18 * (using <tt>Comparable</tt>).
53 dl 1.2 *
54     * @param initialCapacity the initial capacity for this priority queue.
55 dholmes 1.16 * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
56     * than 1
57 dl 1.2 */
58     public PriorityBlockingQueue(int initialCapacity) {
59 dl 1.5 q = new PriorityQueue<E>(initialCapacity, null);
60 dl 1.2 }
61    
62     /**
63 dholmes 1.16 * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
64 dholmes 1.10 * capacity
65 dl 1.2 * that orders its elements according to the specified comparator.
66     *
67     * @param initialCapacity the initial capacity for this priority queue.
68     * @param comparator the comparator used to order this priority queue.
69 dholmes 1.10 * If <tt>null</tt> then the order depends on the elements' natural
70     * ordering.
71 dholmes 1.16 * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
72     * than 1
73 dl 1.2 */
74 tim 1.13 public PriorityBlockingQueue(int initialCapacity,
75 dholmes 1.14 Comparator<? super E> comparator) {
76 dl 1.5 q = new PriorityQueue<E>(initialCapacity, comparator);
77 dl 1.2 }
78    
79     /**
80 dholmes 1.16 * Creates a <tt>PriorityBlockingQueue</tt> containing the elements
81 dl 1.15 * in the specified collection. The priority queue has an initial
82     * capacity of 110% of the size of the specified collection. If
83     * the specified collection is a {@link SortedSet} or a {@link
84     * PriorityQueue}, this priority queue will be sorted according to
85     * the same comparator, or according to its elements' natural
86     * order if the collection is sorted according to its elements'
87     * natural order. Otherwise, this priority queue is ordered
88     * according to its elements' natural order.
89 dl 1.2 *
90 dholmes 1.14 * @param c the collection whose elements are to be placed
91 dl 1.2 * into this priority queue.
92     * @throws ClassCastException if elements of the specified collection
93     * cannot be compared to one another according to the priority
94     * queue's ordering.
95 dholmes 1.14 * @throws NullPointerException if <tt>c</tt> or any element within it
96     * is <tt>null</tt>
97 dl 1.2 */
98 dholmes 1.14 public PriorityBlockingQueue(Collection<? extends E> c) {
99     q = new PriorityQueue<E>(c);
100 dl 1.7 }
101    
102 dholmes 1.10
103 dholmes 1.16 // these first few override just to update doc comments
104 dholmes 1.10
105     /**
106 dholmes 1.16 * Adds the specified element to this queue.
107     * @return <tt>true</tt> (as per the general contract of
108     * <tt>Collection.add</tt>).
109     *
110 dl 1.22 * @throws NullPointerException if the specified element is <tt>null</tt>.
111 dholmes 1.16 * @throws ClassCastException if the specified element cannot be compared
112     * with elements currently in the priority queue according
113     * to the priority queue's ordering.
114 dholmes 1.10 */
115 dholmes 1.16 public boolean add(E o) {
116     return super.add(o);
117 dholmes 1.10 }
118    
119 tim 1.13 /**
120 dholmes 1.16 * Adds all of the elements in the specified collection to this queue.
121     * The behavior of this operation is undefined if
122     * the specified collection is modified while the operation is in
123     * progress. (This implies that the behavior of this call is undefined if
124     * the specified collection is this queue, and this queue is nonempty.)
125     * <p>
126     * This implementation iterates over the specified collection, and adds
127     * each object returned by the iterator to this collection, in turn.
128 dl 1.22 * @param c collection whose elements are to be added to this queue
129     * @return <tt>true</tt> if this queue changed as a result of the
130     * call.
131     * @throws NullPointerException if <tt>c</tt> or any element in <tt>c</tt>
132     * is <tt>null</tt>
133 dholmes 1.16 * @throws ClassCastException if any element cannot be compared
134     * with elements currently in the priority queue according
135     * to the priority queue's ordering.
136 tim 1.13 */
137     public boolean addAll(Collection<? extends E> c) {
138     return super.addAll(c);
139     }
140 dholmes 1.10
141 dholmes 1.16 /**
142     * Returns the comparator used to order this collection, or <tt>null</tt>
143     * if this collection is sorted according to its elements natural ordering
144 tim 1.18 * (using <tt>Comparable</tt>).
145 dholmes 1.16 *
146     * @return the comparator used to order this collection, or <tt>null</tt>
147     * if this collection is sorted according to its elements natural ordering.
148     */
149 dl 1.7 public Comparator comparator() {
150     return q.comparator();
151 dl 1.5 }
152    
153 dholmes 1.16 /**
154 dl 1.22 * Inserts the specified element to this priority queue.
155 dholmes 1.16 *
156 dl 1.22 * @param o the element to add
157 dholmes 1.16 * @return <tt>true</tt>
158     * @throws ClassCastException if the specified element cannot be compared
159     * with elements currently in the priority queue according
160     * to the priority queue's ordering.
161 dl 1.22 * @throws NullPointerException if the specified element is <tt>null</tt>.
162 dholmes 1.16 */
163 dholmes 1.14 public boolean offer(E o) {
164     if (o == null) throw new NullPointerException();
165 dl 1.5 lock.lock();
166     try {
167 dholmes 1.14 boolean ok = q.offer(o);
168 dl 1.5 assert ok;
169     notEmpty.signal();
170     return true;
171 tim 1.19 } finally {
172 tim 1.13 lock.unlock();
173 dl 1.5 }
174     }
175    
176 dholmes 1.16 /**
177     * Adds the specified element to this priority queue. As the queue is
178     * unbounded this method will never block.
179 dl 1.22 * @param o the element to add
180 dholmes 1.16 * @throws ClassCastException if the element cannot be compared
181     * with elements currently in the priority queue according
182     * to the priority queue's ordering.
183 dl 1.22 * @throws NullPointerException if the specified element is <tt>null</tt>.
184 dholmes 1.16 */
185     public void put(E o) {
186 dholmes 1.14 offer(o); // never need to block
187 dl 1.5 }
188    
189 dholmes 1.16 /**
190     * Adds the specified element to this priority queue. As the queue is
191     * unbounded this method will never block.
192 dl 1.22 * @param o the element to add
193 dholmes 1.16 * @param timeout This parameter is ignored as the method never blocks
194     * @param unit This parameter is ignored as the method never blocks
195 dl 1.22 * @return <tt>true</tt>
196 dholmes 1.16 * @throws ClassCastException if the element cannot be compared
197     * with elements currently in the priority queue according
198     * to the priority queue's ordering.
199 dl 1.22 * @throws NullPointerException if the specified element is <tt>null</tt>.
200 dholmes 1.16 */
201     public boolean offer(E o, long timeout, TimeUnit unit) {
202 dholmes 1.14 return offer(o); // never need to block
203 dl 1.5 }
204    
205     public E take() throws InterruptedException {
206     lock.lockInterruptibly();
207     try {
208     try {
209     while (q.size() == 0)
210     notEmpty.await();
211 tim 1.19 } catch (InterruptedException ie) {
212 dl 1.5 notEmpty.signal(); // propagate to non-interrupted thread
213     throw ie;
214     }
215     E x = q.poll();
216     assert x != null;
217     return x;
218 tim 1.19 } finally {
219 dl 1.5 lock.unlock();
220     }
221     }
222    
223    
224     public E poll() {
225     lock.lock();
226     try {
227     return q.poll();
228 tim 1.19 } finally {
229 tim 1.13 lock.unlock();
230 dl 1.5 }
231     }
232    
233     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
234 dholmes 1.10 long nanos = unit.toNanos(timeout);
235 dl 1.5 lock.lockInterruptibly();
236     try {
237     for (;;) {
238     E x = q.poll();
239 tim 1.13 if (x != null)
240 dl 1.5 return x;
241     if (nanos <= 0)
242     return null;
243     try {
244     nanos = notEmpty.awaitNanos(nanos);
245 tim 1.19 } catch (InterruptedException ie) {
246 dl 1.5 notEmpty.signal(); // propagate to non-interrupted thread
247     throw ie;
248     }
249     }
250 tim 1.19 } finally {
251 dl 1.5 lock.unlock();
252     }
253     }
254    
255     public E peek() {
256     lock.lock();
257     try {
258     return q.peek();
259 tim 1.19 } finally {
260 tim 1.13 lock.unlock();
261 dl 1.5 }
262     }
263    
264     public int size() {
265     lock.lock();
266     try {
267     return q.size();
268 tim 1.19 } finally {
269 dl 1.5 lock.unlock();
270     }
271     }
272    
273     /**
274     * Always returns <tt>Integer.MAX_VALUE</tt> because
275 dholmes 1.16 * a <tt>PriorityBlockingQueue</tt> is not capacity constrained.
276 dl 1.5 * @return <tt>Integer.MAX_VALUE</tt>
277     */
278     public int remainingCapacity() {
279     return Integer.MAX_VALUE;
280     }
281    
282 dholmes 1.14 public boolean remove(Object o) {
283 dl 1.5 lock.lock();
284     try {
285 dholmes 1.14 return q.remove(o);
286 tim 1.19 } finally {
287 dl 1.5 lock.unlock();
288     }
289     }
290    
291 dholmes 1.14 public boolean contains(Object o) {
292 dl 1.5 lock.lock();
293     try {
294 dholmes 1.14 return q.contains(o);
295 tim 1.19 } finally {
296 dl 1.5 lock.unlock();
297     }
298     }
299    
300     public Object[] toArray() {
301     lock.lock();
302     try {
303     return q.toArray();
304 tim 1.19 } finally {
305 dl 1.5 lock.unlock();
306     }
307     }
308    
309    
310     public String toString() {
311     lock.lock();
312     try {
313     return q.toString();
314 tim 1.19 } finally {
315 dl 1.5 lock.unlock();
316     }
317     }
318    
319 dl 1.17 /**
320     * Atomically removes all of the elements from this delay queue.
321     * The queue will be empty after this call returns.
322     */
323     public void clear() {
324     lock.lock();
325     try {
326     q.clear();
327 tim 1.19 } finally {
328 dl 1.17 lock.unlock();
329     }
330     }
331    
332 dl 1.5 public <T> T[] toArray(T[] a) {
333     lock.lock();
334     try {
335     return q.toArray(a);
336 tim 1.19 } finally {
337 dl 1.5 lock.unlock();
338     }
339     }
340    
341 dholmes 1.16 /**
342 dl 1.23 * Returns an iterator over the elements in this queue. The
343     * iterator does not return the elements in any particular order.
344     * The returned iterator is a thread-safe "fast-fail" iterator
345     * that will throw {@link
346     * java.util.ConcurrentModificationException} upon detected
347     * interference.
348 dholmes 1.16 *
349     * @return an iterator over the elements in this queue.
350     */
351 dl 1.5 public Iterator<E> iterator() {
352     lock.lock();
353     try {
354     return new Itr(q.iterator());
355 tim 1.19 } finally {
356 dl 1.5 lock.unlock();
357     }
358     }
359    
360     private class Itr<E> implements Iterator<E> {
361     private final Iterator<E> iter;
362 tim 1.13 Itr(Iterator<E> i) {
363     iter = i;
364 dl 1.5 }
365    
366 tim 1.13 public boolean hasNext() {
367 dl 1.5 /*
368     * No sync -- we rely on underlying hasNext to be
369     * stateless, in which case we can return true by mistake
370     * only when next() willl subsequently throw
371     * ConcurrentModificationException.
372     */
373     return iter.hasNext();
374 tim 1.13 }
375    
376     public E next() {
377 dl 1.5 lock.lock();
378     try {
379     return iter.next();
380 tim 1.19 } finally {
381 dl 1.5 lock.unlock();
382     }
383 tim 1.13 }
384    
385     public void remove() {
386 dl 1.5 lock.lock();
387     try {
388     iter.remove();
389 tim 1.19 } finally {
390 dl 1.5 lock.unlock();
391     }
392 tim 1.13 }
393 dl 1.5 }
394    
395     /**
396     * Save the state to a stream (that is, serialize it). This
397     * merely wraps default serialization within lock. The
398     * serialization strategy for items is left to underlying
399     * Queue. Note that locking is not needed on deserialization, so
400     * readObject is not defined, just relying on default.
401     */
402     private void writeObject(java.io.ObjectOutputStream s)
403     throws java.io.IOException {
404     lock.lock();
405     try {
406     s.defaultWriteObject();
407 tim 1.19 } finally {
408 dl 1.5 lock.unlock();
409     }
410 tim 1.1 }
411    
412     }