ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/PriorityBlockingQueue.java
Revision: 1.24
Committed: Mon Sep 15 12:02:46 2003 UTC (20 years, 8 months ago) by dl
Branch: MAIN
Changes since 1.23: +9 -29 lines
Log Message:
Fix some javadoc inconsistencies

File Contents

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