ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/PriorityBlockingQueue.java
Revision: 1.56
Committed: Mon Sep 20 20:23:52 2010 UTC (13 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.55: +7 -7 lines
Log Message:
Fix javadoc code samples to use <pre>  {@code so that we can replace &lt; with <, etc.

File Contents

# User Rev Content
1 dl 1.2 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3 dl 1.33 * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/licenses/publicdomain
5 dl 1.2 */
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 dl 1.25 * An unbounded {@linkplain BlockingQueue blocking queue} that uses
14     * the same ordering rules as class {@link PriorityQueue} and supplies
15     * blocking retrieval operations. While this queue is logically
16 dl 1.24 * unbounded, attempted additions may fail due to resource exhaustion
17 dl 1.25 * (causing <tt>OutOfMemoryError</tt>). This class does not permit
18 jsr166 1.42 * <tt>null</tt> elements. A priority queue relying on {@linkplain
19     * Comparable natural ordering} also does not permit insertion of
20     * non-comparable objects (doing so results in
21     * <tt>ClassCastException</tt>).
22 dl 1.20 *
23 dl 1.38 * <p>This class and its iterator implement all of the
24     * <em>optional</em> methods of the {@link Collection} and {@link
25 dl 1.41 * Iterator} interfaces. The Iterator provided in method {@link
26     * #iterator()} is <em>not</em> guaranteed to traverse the elements of
27     * the PriorityBlockingQueue in any particular order. If you need
28     * ordered traversal, consider using
29     * <tt>Arrays.sort(pq.toArray())</tt>. Also, method <tt>drainTo</tt>
30     * can be used to <em>remove</em> some or all elements in priority
31     * order and place them in another collection.
32     *
33     * <p>Operations on this class make no guarantees about the ordering
34     * of elements with equal priority. If you need to enforce an
35     * ordering, you can define custom classes or comparators that use a
36     * secondary key to break ties in primary priority values. For
37     * example, here is a class that applies first-in-first-out
38     * tie-breaking to comparable elements. To use it, you would insert a
39     * <tt>new FIFOEntry(anEntry)</tt> instead of a plain entry object.
40     *
41 jsr166 1.56 * <pre> {@code
42     * class FIFOEntry<E extends Comparable<? super E>>
43     * implements Comparable<FIFOEntry<E>> {
44 jsr166 1.47 * final static AtomicLong seq = new AtomicLong();
45 dl 1.41 * final long seqNum;
46     * final E entry;
47     * public FIFOEntry(E entry) {
48     * seqNum = seq.getAndIncrement();
49     * this.entry = entry;
50     * }
51     * public E getEntry() { return entry; }
52 jsr166 1.56 * public int compareTo(FIFOEntry<E> other) {
53 dl 1.41 * int res = entry.compareTo(other.entry);
54 jsr166 1.56 * if (res == 0 && other.entry != this.entry)
55     * res = (seqNum < other.seqNum ? -1 : 1);
56 dl 1.41 * return res;
57     * }
58 jsr166 1.56 * }}</pre>
59 dl 1.20 *
60 dl 1.35 * <p>This class is a member of the
61 jsr166 1.53 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
62 dl 1.35 * Java Collections Framework</a>.
63     *
64 dl 1.6 * @since 1.5
65     * @author Doug Lea
66 dl 1.29 * @param <E> the type of elements held in this collection
67 dl 1.28 */
68 dl 1.5 public class PriorityBlockingQueue<E> extends AbstractQueue<E>
69 dl 1.15 implements BlockingQueue<E>, java.io.Serializable {
70 dl 1.21 private static final long serialVersionUID = 5595510919245408276L;
71 tim 1.1
72 jsr166 1.55 final PriorityQueue<E> q;
73     final ReentrantLock lock = new ReentrantLock(true);
74 dl 1.32 private final Condition notEmpty = lock.newCondition();
75 dl 1.5
76 dl 1.2 /**
77 jsr166 1.42 * Creates a <tt>PriorityBlockingQueue</tt> with the default
78     * initial capacity (11) that orders its elements according to
79     * their {@linkplain Comparable natural ordering}.
80 dl 1.2 */
81     public PriorityBlockingQueue() {
82 dl 1.5 q = new PriorityQueue<E>();
83 dl 1.2 }
84    
85     /**
86 jsr166 1.42 * Creates a <tt>PriorityBlockingQueue</tt> with the specified
87     * initial capacity that orders its elements according to their
88     * {@linkplain Comparable natural ordering}.
89 dl 1.2 *
90 jsr166 1.42 * @param initialCapacity the initial capacity for this priority queue
91 dholmes 1.16 * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
92 jsr166 1.52 * than 1
93 dl 1.2 */
94     public PriorityBlockingQueue(int initialCapacity) {
95 dl 1.5 q = new PriorityQueue<E>(initialCapacity, null);
96 dl 1.2 }
97    
98     /**
99 dholmes 1.16 * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
100 jsr166 1.39 * capacity that orders its elements according to the specified
101     * comparator.
102 dl 1.2 *
103 jsr166 1.42 * @param initialCapacity the initial capacity for this priority queue
104 jsr166 1.52 * @param comparator the comparator that will be used to order this
105     * priority queue. If {@code null}, the {@linkplain Comparable
106     * natural ordering} of the elements will be used.
107 dholmes 1.16 * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
108 jsr166 1.52 * than 1
109 dl 1.2 */
110 tim 1.13 public PriorityBlockingQueue(int initialCapacity,
111 dholmes 1.14 Comparator<? super E> comparator) {
112 dl 1.5 q = new PriorityQueue<E>(initialCapacity, comparator);
113 dl 1.2 }
114    
115     /**
116 dholmes 1.16 * Creates a <tt>PriorityBlockingQueue</tt> containing the elements
117 jsr166 1.52 * in the specified collection. If the specified collection is a
118     * {@link SortedSet} or a {@link PriorityQueue}, this
119     * priority queue will be ordered according to the same ordering.
120     * Otherwise, this priority queue will be ordered according to the
121     * {@linkplain Comparable natural ordering} of its elements.
122 dl 1.2 *
123 jsr166 1.52 * @param c the collection whose elements are to be placed
124     * into this priority queue
125 dl 1.2 * @throws ClassCastException if elements of the specified collection
126     * cannot be compared to one another according to the priority
127 jsr166 1.52 * queue's ordering
128 jsr166 1.42 * @throws NullPointerException if the specified collection or any
129     * of its elements are null
130 dl 1.2 */
131 dholmes 1.14 public PriorityBlockingQueue(Collection<? extends E> c) {
132     q = new PriorityQueue<E>(c);
133 dl 1.7 }
134    
135 dholmes 1.10 /**
136 jsr166 1.42 * Inserts the specified element into this priority queue.
137     *
138 jsr166 1.40 * @param e the element to add
139 jsr166 1.48 * @return <tt>true</tt> (as specified by {@link Collection#add})
140 dholmes 1.16 * @throws ClassCastException if the specified element cannot be compared
141 jsr166 1.42 * with elements currently in the priority queue according to the
142     * priority queue's ordering
143     * @throws NullPointerException if the specified element is null
144 dholmes 1.10 */
145 jsr166 1.40 public boolean add(E e) {
146 jsr166 1.42 return offer(e);
147 dl 1.5 }
148    
149 dholmes 1.16 /**
150 dl 1.24 * Inserts the specified element into this priority queue.
151 dholmes 1.16 *
152 jsr166 1.40 * @param e the element to add
153 jsr166 1.48 * @return <tt>true</tt> (as specified by {@link Queue#offer})
154 dholmes 1.16 * @throws ClassCastException if the specified element cannot be compared
155 jsr166 1.42 * with elements currently in the priority queue according to the
156     * priority queue's ordering
157     * @throws NullPointerException if the specified element is null
158 dholmes 1.16 */
159 jsr166 1.40 public boolean offer(E e) {
160 dl 1.31 final ReentrantLock lock = this.lock;
161 dl 1.5 lock.lock();
162     try {
163 jsr166 1.40 boolean ok = q.offer(e);
164 dl 1.5 assert ok;
165     notEmpty.signal();
166     return true;
167 tim 1.19 } finally {
168 tim 1.13 lock.unlock();
169 dl 1.5 }
170     }
171    
172 dholmes 1.16 /**
173 jsr166 1.42 * Inserts the specified element into this priority queue. As the queue is
174 dholmes 1.16 * unbounded this method will never block.
175 jsr166 1.42 *
176 jsr166 1.40 * @param e the element to add
177 jsr166 1.42 * @throws ClassCastException if the specified element cannot be compared
178     * with elements currently in the priority queue according to the
179     * priority queue's ordering
180     * @throws NullPointerException if the specified element is null
181 dholmes 1.16 */
182 jsr166 1.40 public void put(E e) {
183     offer(e); // never need to block
184 dl 1.5 }
185    
186 dholmes 1.16 /**
187 dl 1.24 * Inserts the specified element into this priority queue. As the queue is
188 dholmes 1.16 * unbounded this method will never block.
189 jsr166 1.42 *
190 jsr166 1.40 * @param e the element to add
191 dholmes 1.16 * @param timeout This parameter is ignored as the method never blocks
192     * @param unit This parameter is ignored as the method never blocks
193 dl 1.22 * @return <tt>true</tt>
194 jsr166 1.42 * @throws ClassCastException if the specified element cannot be compared
195     * with elements currently in the priority queue according to the
196     * priority queue's ordering
197     * @throws NullPointerException if the specified element is null
198 dholmes 1.16 */
199 jsr166 1.40 public boolean offer(E e, long timeout, TimeUnit unit) {
200     return offer(e); // never need to block
201 dl 1.5 }
202    
203 jsr166 1.42 public E poll() {
204     final ReentrantLock lock = this.lock;
205     lock.lock();
206     try {
207     return q.poll();
208     } finally {
209     lock.unlock();
210     }
211     }
212    
213 dl 1.5 public E take() throws InterruptedException {
214 dl 1.31 final ReentrantLock lock = this.lock;
215 dl 1.5 lock.lockInterruptibly();
216     try {
217 jsr166 1.55 E x;
218     while ( (x = q.poll()) == null)
219     notEmpty.await();
220 dl 1.5 return x;
221 tim 1.19 } finally {
222 dl 1.5 lock.unlock();
223     }
224     }
225    
226     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
227 dholmes 1.10 long nanos = unit.toNanos(timeout);
228 dl 1.31 final ReentrantLock lock = this.lock;
229 dl 1.5 lock.lockInterruptibly();
230     try {
231 jsr166 1.55 E x;
232     while ( (x = q.poll()) == null) {
233 dl 1.5 if (nanos <= 0)
234     return null;
235 jsr166 1.55 nanos = notEmpty.awaitNanos(nanos);
236 dl 1.5 }
237 jsr166 1.55 return x;
238 tim 1.19 } finally {
239 dl 1.5 lock.unlock();
240     }
241     }
242    
243     public E peek() {
244 dl 1.31 final ReentrantLock lock = this.lock;
245 dl 1.5 lock.lock();
246     try {
247     return q.peek();
248 tim 1.19 } finally {
249 tim 1.13 lock.unlock();
250 dl 1.5 }
251     }
252    
253 jsr166 1.42 /**
254     * Returns the comparator used to order the elements in this queue,
255     * or <tt>null</tt> if this queue uses the {@linkplain Comparable
256     * natural ordering} of its elements.
257     *
258     * @return the comparator used to order the elements in this queue,
259     * or <tt>null</tt> if this queue uses the natural
260 jsr166 1.52 * ordering of its elements
261 jsr166 1.42 */
262     public Comparator<? super E> comparator() {
263     return q.comparator();
264     }
265    
266 dl 1.5 public int size() {
267 dl 1.31 final ReentrantLock lock = this.lock;
268 dl 1.5 lock.lock();
269     try {
270     return q.size();
271 tim 1.19 } finally {
272 dl 1.5 lock.unlock();
273     }
274     }
275    
276     /**
277     * Always returns <tt>Integer.MAX_VALUE</tt> because
278 dholmes 1.16 * a <tt>PriorityBlockingQueue</tt> is not capacity constrained.
279 dl 1.5 * @return <tt>Integer.MAX_VALUE</tt>
280     */
281     public int remainingCapacity() {
282     return Integer.MAX_VALUE;
283     }
284    
285 dl 1.37 /**
286 jsr166 1.42 * Removes a single instance of the specified element from this queue,
287 jsr166 1.52 * if it is present. More formally, removes an element {@code e} such
288     * that {@code o.equals(e)}, if this queue contains one or more such
289     * elements. Returns {@code true} if and only if this queue contained
290     * the specified element (or equivalently, if this queue changed as a
291     * result of the call).
292 jsr166 1.42 *
293     * @param o element to be removed from this queue, if present
294     * @return <tt>true</tt> if this queue changed as a result of the call
295 dl 1.37 */
296 dholmes 1.14 public boolean remove(Object o) {
297 dl 1.31 final ReentrantLock lock = this.lock;
298 dl 1.5 lock.lock();
299     try {
300 dholmes 1.14 return q.remove(o);
301 tim 1.19 } finally {
302 dl 1.5 lock.unlock();
303     }
304     }
305    
306 jsr166 1.42 /**
307 jsr166 1.52 * Returns {@code true} if this queue contains the specified element.
308     * More formally, returns {@code true} if and only if this queue contains
309     * at least one element {@code e} such that {@code o.equals(e)}.
310 jsr166 1.42 *
311     * @param o object to be checked for containment in this queue
312     * @return <tt>true</tt> if this queue contains the specified element
313     */
314 dholmes 1.14 public boolean contains(Object o) {
315 dl 1.31 final ReentrantLock lock = this.lock;
316 dl 1.5 lock.lock();
317     try {
318 dholmes 1.14 return q.contains(o);
319 tim 1.19 } finally {
320 dl 1.5 lock.unlock();
321     }
322     }
323    
324 jsr166 1.42 /**
325     * Returns an array containing all of the elements in this queue.
326     * The returned array elements are in no particular order.
327     *
328     * <p>The returned array will be "safe" in that no references to it are
329     * maintained by this queue. (In other words, this method must allocate
330     * a new array). The caller is thus free to modify the returned array.
331 jsr166 1.43 *
332 jsr166 1.42 * <p>This method acts as bridge between array-based and collection-based
333     * APIs.
334     *
335     * @return an array containing all of the elements in this queue
336     */
337 dl 1.5 public Object[] toArray() {
338 dl 1.31 final ReentrantLock lock = this.lock;
339 dl 1.5 lock.lock();
340     try {
341     return q.toArray();
342 tim 1.19 } finally {
343 dl 1.5 lock.unlock();
344     }
345     }
346    
347 jsr166 1.52
348 dl 1.5 public String toString() {
349 dl 1.31 final ReentrantLock lock = this.lock;
350 dl 1.5 lock.lock();
351     try {
352     return q.toString();
353 tim 1.19 } finally {
354 dl 1.5 lock.unlock();
355     }
356     }
357    
358 jsr166 1.42 /**
359     * @throws UnsupportedOperationException {@inheritDoc}
360     * @throws ClassCastException {@inheritDoc}
361     * @throws NullPointerException {@inheritDoc}
362     * @throws IllegalArgumentException {@inheritDoc}
363     */
364 dl 1.26 public int drainTo(Collection<? super E> c) {
365     if (c == null)
366     throw new NullPointerException();
367     if (c == this)
368     throw new IllegalArgumentException();
369 dl 1.31 final ReentrantLock lock = this.lock;
370 dl 1.26 lock.lock();
371     try {
372     int n = 0;
373     E e;
374     while ( (e = q.poll()) != null) {
375     c.add(e);
376     ++n;
377     }
378     return n;
379     } finally {
380     lock.unlock();
381     }
382     }
383    
384 jsr166 1.42 /**
385     * @throws UnsupportedOperationException {@inheritDoc}
386     * @throws ClassCastException {@inheritDoc}
387     * @throws NullPointerException {@inheritDoc}
388     * @throws IllegalArgumentException {@inheritDoc}
389     */
390 dl 1.26 public int drainTo(Collection<? super E> c, int maxElements) {
391     if (c == null)
392     throw new NullPointerException();
393     if (c == this)
394     throw new IllegalArgumentException();
395     if (maxElements <= 0)
396     return 0;
397 dl 1.31 final ReentrantLock lock = this.lock;
398 dl 1.26 lock.lock();
399     try {
400     int n = 0;
401     E e;
402     while (n < maxElements && (e = q.poll()) != null) {
403     c.add(e);
404     ++n;
405     }
406     return n;
407     } finally {
408     lock.unlock();
409     }
410     }
411    
412 dl 1.17 /**
413 dl 1.37 * Atomically removes all of the elements from this queue.
414 dl 1.17 * The queue will be empty after this call returns.
415     */
416     public void clear() {
417 dl 1.31 final ReentrantLock lock = this.lock;
418 dl 1.17 lock.lock();
419     try {
420     q.clear();
421 tim 1.19 } finally {
422 dl 1.17 lock.unlock();
423     }
424     }
425    
426 jsr166 1.42 /**
427     * Returns an array containing all of the elements in this queue; the
428     * runtime type of the returned array is that of the specified array.
429     * The returned array elements are in no particular order.
430     * If the queue fits in the specified array, it is returned therein.
431     * Otherwise, a new array is allocated with the runtime type of the
432     * specified array and the size of this queue.
433     *
434     * <p>If this queue fits in the specified array with room to spare
435     * (i.e., the array has more elements than this queue), the element in
436     * the array immediately following the end of the queue is set to
437     * <tt>null</tt>.
438     *
439     * <p>Like the {@link #toArray()} method, this method acts as bridge between
440     * array-based and collection-based APIs. Further, this method allows
441     * precise control over the runtime type of the output array, and may,
442     * under certain circumstances, be used to save allocation costs.
443     *
444     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
445     * The following code can be used to dump the queue into a newly
446     * allocated array of <tt>String</tt>:
447     *
448     * <pre>
449     * String[] y = x.toArray(new String[0]);</pre>
450     *
451     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
452     * <tt>toArray()</tt>.
453     *
454     * @param a the array into which the elements of the queue are to
455     * be stored, if it is big enough; otherwise, a new array of the
456     * same runtime type is allocated for this purpose
457     * @return an array containing all of the elements in this queue
458     * @throws ArrayStoreException if the runtime type of the specified array
459     * is not a supertype of the runtime type of every element in
460     * this queue
461     * @throws NullPointerException if the specified array is null
462     */
463 dl 1.5 public <T> T[] toArray(T[] a) {
464 dl 1.31 final ReentrantLock lock = this.lock;
465 dl 1.5 lock.lock();
466     try {
467     return q.toArray(a);
468 tim 1.19 } finally {
469 dl 1.5 lock.unlock();
470     }
471     }
472    
473 dholmes 1.16 /**
474 dl 1.23 * Returns an iterator over the elements in this queue. The
475     * iterator does not return the elements in any particular order.
476 dl 1.51 * The returned <tt>Iterator</tt> is a "weakly consistent"
477     * iterator that will never throw {@link
478     * ConcurrentModificationException}, and guarantees to traverse
479     * elements as they existed upon construction of the iterator, and
480     * may (but is not guaranteed to) reflect any modifications
481     * subsequent to construction.
482 dholmes 1.16 *
483 jsr166 1.42 * @return an iterator over the elements in this queue
484 dholmes 1.16 */
485 dl 1.5 public Iterator<E> iterator() {
486 dl 1.51 return new Itr(toArray());
487 dl 1.5 }
488    
489 dl 1.49 /**
490     * Snapshot iterator that works off copy of underlying q array.
491     */
492 dl 1.51 private class Itr implements Iterator<E> {
493 dl 1.49 final Object[] array; // Array of all elements
494 jsr166 1.54 int cursor; // index of next element to return;
495     int lastRet; // index of last element, or -1 if no such
496 jsr166 1.50
497 dl 1.49 Itr(Object[] array) {
498     lastRet = -1;
499     this.array = array;
500 dl 1.5 }
501    
502 tim 1.13 public boolean hasNext() {
503 dl 1.49 return cursor < array.length;
504 tim 1.13 }
505    
506     public E next() {
507 dl 1.49 if (cursor >= array.length)
508     throw new NoSuchElementException();
509     lastRet = cursor;
510     return (E)array[cursor++];
511 tim 1.13 }
512    
513     public void remove() {
514 jsr166 1.50 if (lastRet < 0)
515 jsr166 1.54 throw new IllegalStateException();
516 dl 1.49 Object x = array[lastRet];
517     lastRet = -1;
518     // Traverse underlying queue to find == element,
519     // not just a .equals element.
520 dl 1.5 lock.lock();
521     try {
522 dl 1.49 for (Iterator it = q.iterator(); it.hasNext(); ) {
523     if (it.next() == x) {
524     it.remove();
525     return;
526     }
527     }
528 tim 1.19 } finally {
529 dl 1.5 lock.unlock();
530     }
531 tim 1.13 }
532 dl 1.5 }
533    
534     /**
535 jsr166 1.52 * Saves the state to a stream (that is, serializes it). This
536 dl 1.5 * merely wraps default serialization within lock. The
537     * serialization strategy for items is left to underlying
538     * Queue. Note that locking is not needed on deserialization, so
539     * readObject is not defined, just relying on default.
540     */
541     private void writeObject(java.io.ObjectOutputStream s)
542     throws java.io.IOException {
543     lock.lock();
544     try {
545     s.defaultWriteObject();
546 tim 1.19 } finally {
547 dl 1.5 lock.unlock();
548     }
549 tim 1.1 }
550    
551     }