ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/PriorityBlockingQueue.java
Revision: 1.20
Committed: Sun Aug 24 23:32:25 2003 UTC (20 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.19: +6 -0 lines
Log Message:
Kill ScheduledExecutor Date methods; Documentation clarifications

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