ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java (file contents):
Revision 1.49 by jsr166, Mon May 2 08:35:49 2005 UTC vs.
Revision 1.50 by jsr166, Tue May 17 17:11:59 2005 UTC

# Line 20 | Line 20 | import java.util.*;
20   * <p>This is a classic &quot;bounded buffer&quot;, in which a
21   * fixed-sized array holds elements inserted by producers and
22   * extracted by consumers.  Once created, the capacity cannot be
23 < * increased.  Attempts to put an element to a full queue will
24 < * result in the put operation blocking; attempts to retrieve an
23 > * increased.  Attempts to <tt>put</tt> an element into a full queue
24 > * will result in the operation blocking; attempts to <tt>take</tt> an
25   * element from an empty queue will similarly block.
26   *
27   * <p> This class supports an optional fairness policy for ordering
# Line 140 | Line 140 | public class ArrayBlockingQueue<E> exten
140      /**
141       * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
142       * capacity and default access policy.
143 +     *
144       * @param capacity the capacity of this queue
145       * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
146       */
# Line 150 | Line 151 | public class ArrayBlockingQueue<E> exten
151      /**
152       * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
153       * capacity and the specified access policy.
154 +     *
155       * @param capacity the capacity of this queue
156       * @param fair if <tt>true</tt> then queue accesses for threads blocked
157 <     * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
158 <     * the access order is unspecified.
157 >     *        on insertion or removal, are processed in FIFO order;
158 >     *        if <tt>false</tt> the access order is unspecified.
159       * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
160       */
161      public ArrayBlockingQueue(int capacity, boolean fair) {
# Line 170 | Line 172 | public class ArrayBlockingQueue<E> exten
172       * capacity, the specified access policy and initially containing the
173       * elements of the given collection,
174       * added in traversal order of the collection's iterator.
175 +     *
176       * @param capacity the capacity of this queue
177       * @param fair if <tt>true</tt> then queue accesses for threads blocked
178 <     * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
179 <     * the access order is unspecified.
178 >     *        on insertion or removal, are processed in FIFO order;
179 >     *        if <tt>false</tt> the access order is unspecified.
180       * @param c the collection of elements to initially contain
181       * @throws IllegalArgumentException if <tt>capacity</tt> is less than
182 <     * <tt>c.size()</tt>, or less than 1.
183 <     * @throws NullPointerException if <tt>c</tt> or any element within it
184 <     *         is <tt>null</tt>.
182 >     *         <tt>c.size()</tt>, or less than 1.
183 >     * @throws NullPointerException if the specified collection or any
184 >     *         of its elements are null
185       */
186      public ArrayBlockingQueue(int capacity, boolean fair,
187                                Collection<? extends E> c) {
# Line 191 | Line 194 | public class ArrayBlockingQueue<E> exten
194      }
195  
196      /**
197 <     * Inserts the specified element at the tail of this queue if possible,
198 <     * returning immediately if this queue is full.
197 >     * Inserts the specified element at the tail of this queue if it is
198 >     * possible to do so immediately without exceeding the queue's capacity,
199 >     * returning <tt>true</tt> upon success and throwing an
200 >     * <tt>IllegalStateException</tt> if this queue is full.
201       *
202 <     * @param e the element to add.
203 <     * @return <tt>true</tt> if it was possible to add the element to
204 <     *         this queue, else <tt>false</tt>
205 <     * @throws NullPointerException if the specified element is <tt>null</tt>.
202 >     * @param e the element to add
203 >     * @return <tt>true</tt> (as per the spec for {@link Collection#add})
204 >     * @throws IllegalStateException if this queue is full
205 >     * @throws NullPointerException if the specified element is null
206 >     */
207 >    public boolean add(E e) {
208 >        return super.add(e);
209 >    }
210 >
211 >    /**
212 >     * Inserts the specified element at the tail of this queue if it is
213 >     * possible to do so immediately without exceeding the queue's capacity,
214 >     * returning <tt>true</tt> upon success and <tt>false</tt> if this queue
215 >     * is full.  This method is generally preferable to method {@link #add},
216 >     * which can fail to insert an element only by throwing an exception.
217 >     *
218 >     * @throws NullPointerException if the specified element is null
219       */
220      public boolean offer(E e) {
221          if (e == null) throw new NullPointerException();
# Line 216 | Line 234 | public class ArrayBlockingQueue<E> exten
234      }
235  
236      /**
237 <     * Inserts the specified element at the tail of this queue, waiting if
238 <     * necessary up to the specified wait time for space to become available.
239 <     * @param e the element to add
240 <     * @param timeout how long to wait before giving up, in units of
241 <     * <tt>unit</tt>
242 <     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
243 <     * <tt>timeout</tt> parameter
244 <     * @return <tt>true</tt> if successful, or <tt>false</tt> if
245 <     * the specified waiting time elapses before space is available.
246 <     * @throws InterruptedException if interrupted while waiting.
247 <     * @throws NullPointerException if the specified element is <tt>null</tt>.
237 >     * Inserts the specified element at the tail of this queue, waiting
238 >     * for space to become available if the queue is full.
239 >     *
240 >     * @throws InterruptedException {@inheritDoc}
241 >     * @throws NullPointerException {@inheritDoc}
242 >     */
243 >    public void put(E e) throws InterruptedException {
244 >        if (e == null) throw new NullPointerException();
245 >        final E[] items = this.items;
246 >        final ReentrantLock lock = this.lock;
247 >        lock.lockInterruptibly();
248 >        try {
249 >            try {
250 >                while (count == items.length)
251 >                    notFull.await();
252 >            } catch (InterruptedException ie) {
253 >                notFull.signal(); // propagate to non-interrupted thread
254 >                throw ie;
255 >            }
256 >            insert(e);
257 >        } finally {
258 >            lock.unlock();
259 >        }
260 >    }
261 >
262 >    /**
263 >     * Inserts the specified element at the tail of this queue, waiting
264 >     * up to the specified wait time for space to become available if
265 >     * the queue is full.
266 >     *
267 >     * @throws InterruptedException {@inheritDoc}
268 >     * @throws NullPointerException {@inheritDoc}
269       */
270      public boolean offer(E e, long timeout, TimeUnit unit)
271          throws InterruptedException {
# Line 255 | Line 294 | public class ArrayBlockingQueue<E> exten
294          }
295      }
296  
258
297      public E poll() {
298          final ReentrantLock lock = this.lock;
299          lock.lock();
# Line 269 | Line 307 | public class ArrayBlockingQueue<E> exten
307          }
308      }
309  
310 +    public E take() throws InterruptedException {
311 +        final ReentrantLock lock = this.lock;
312 +        lock.lockInterruptibly();
313 +        try {
314 +            try {
315 +                while (count == 0)
316 +                    notEmpty.await();
317 +            } catch (InterruptedException ie) {
318 +                notEmpty.signal(); // propagate to non-interrupted thread
319 +                throw ie;
320 +            }
321 +            E x = extract();
322 +            return x;
323 +        } finally {
324 +            lock.unlock();
325 +        }
326 +    }
327 +
328      public E poll(long timeout, TimeUnit unit) throws InterruptedException {
329          final ReentrantLock lock = this.lock;
330          lock.lockInterruptibly();
# Line 294 | Line 350 | public class ArrayBlockingQueue<E> exten
350          }
351      }
352  
297    /**
298     * Removes a single instance of the specified element from this
299     * queue, if it is present.
300     */
301    public boolean remove(Object o) {
302        if (o == null) return false;
303        final E[] items = this.items;
304        final ReentrantLock lock = this.lock;
305        lock.lock();
306        try {
307            int i = takeIndex;
308            int k = 0;
309            for (;;) {
310                if (k++ >= count)
311                    return false;
312                if (o.equals(items[i])) {
313                    removeAt(i);
314                    return true;
315                }
316                i = inc(i);
317            }
318
319        } finally {
320            lock.unlock();
321        }
322    }
323
353      public E peek() {
354          final ReentrantLock lock = this.lock;
355          lock.lock();
# Line 331 | Line 360 | public class ArrayBlockingQueue<E> exten
360          }
361      }
362  
334    public E take() throws InterruptedException {
335        final ReentrantLock lock = this.lock;
336        lock.lockInterruptibly();
337        try {
338            try {
339                while (count == 0)
340                    notEmpty.await();
341            } catch (InterruptedException ie) {
342                notEmpty.signal(); // propagate to non-interrupted thread
343                throw ie;
344            }
345            E x = extract();
346            return x;
347        } finally {
348            lock.unlock();
349        }
350    }
351
352    /**
353     * Adds the specified element to the tail of this queue, waiting if
354     * necessary for space to become available.
355     * @param e the element to add
356     * @throws InterruptedException if interrupted while waiting.
357     * @throws NullPointerException if the specified element is <tt>null</tt>.
358     */
359    public void put(E e) throws InterruptedException {
360        if (e == null) throw new NullPointerException();
361        final E[] items = this.items;
362        final ReentrantLock lock = this.lock;
363        lock.lockInterruptibly();
364        try {
365            try {
366                while (count == items.length)
367                    notFull.await();
368            } catch (InterruptedException ie) {
369                notFull.signal(); // propagate to non-interrupted thread
370                throw ie;
371            }
372            insert(e);
373        } finally {
374            lock.unlock();
375        }
376    }
377
363      // this doc comment is overridden to remove the reference to collections
364      // greater in size than Integer.MAX_VALUE
365      /**
366       * Returns the number of elements in this queue.
367       *
368 <     * @return  the number of elements in this queue.
368 >     * @return the number of elements in this queue
369       */
370      public int size() {
371          final ReentrantLock lock = this.lock;
# Line 403 | Line 388 | public class ArrayBlockingQueue<E> exten
388       * <p>Note that you <em>cannot</em> always tell if an attempt to insert
389       * an element will succeed by inspecting <tt>remainingCapacity</tt>
390       * because it may be the case that another thread is about to
391 <     * <tt>put</tt> or <tt>take</tt> an element.
391 >     * insert or remove an element.
392       */
393      public int remainingCapacity() {
394          final ReentrantLock lock = this.lock;
# Line 415 | Line 400 | public class ArrayBlockingQueue<E> exten
400          }
401      }
402  
403 +    /**
404 +     * Removes a single instance of the specified element from this queue,
405 +     * if it is present.  More formally, removes an element <tt>e</tt> such
406 +     * that <tt>o.equals(e)</tt>, if this queue contains one or more such
407 +     * elements.
408 +     * Returns <tt>true</tt> if this queue contained the specified element
409 +     * (or equivalently, if this queue changed as a result of the call).
410 +     *
411 +     * @param o element to be removed from this queue, if present
412 +     * @return <tt>true</tt> if this queue changed as a result of the call
413 +     */
414 +    public boolean remove(Object o) {
415 +        if (o == null) return false;
416 +        final E[] items = this.items;
417 +        final ReentrantLock lock = this.lock;
418 +        lock.lock();
419 +        try {
420 +            int i = takeIndex;
421 +            int k = 0;
422 +            for (;;) {
423 +                if (k++ >= count)
424 +                    return false;
425 +                if (o.equals(items[i])) {
426 +                    removeAt(i);
427 +                    return true;
428 +                }
429 +                i = inc(i);
430 +            }
431 +
432 +        } finally {
433 +            lock.unlock();
434 +        }
435 +    }
436  
437 +    /**
438 +     * Returns <tt>true</tt> if this queue contains the specified element.
439 +     * More formally, returns <tt>true</tt> if and only if this queue contains
440 +     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
441 +     *
442 +     * @param o object to be checked for containment in this queue
443 +     * @return <tt>true</tt> if this queue contains the specified element
444 +     */
445      public boolean contains(Object o) {
446          if (o == null) return false;
447          final E[] items = this.items;
# Line 435 | Line 461 | public class ArrayBlockingQueue<E> exten
461          }
462      }
463  
464 +    /**
465 +     * Returns an array containing all of the elements in this queue, in
466 +     * proper sequence.
467 +     *
468 +     * <p>The returned array will be "safe" in that no references to it are
469 +     * maintained by this queue.  (In other words, this method must allocate
470 +     * a new array).  The caller is thus free to modify the returned array.
471 +     *
472 +     * <p>This method acts as bridge between array-based and collection-based
473 +     * APIs.
474 +     *
475 +     * @return an array containing all of the elements in this queue
476 +     */
477      public Object[] toArray() {
478          final E[] items = this.items;
479          final ReentrantLock lock = this.lock;
# Line 453 | Line 492 | public class ArrayBlockingQueue<E> exten
492          }
493      }
494  
495 +    /**
496 +     * Returns an array containing all of the elements in this queue, in
497 +     * proper sequence; the runtime type of the returned array is that of
498 +     * the specified array.  If the queue fits in the specified array, it
499 +     * is returned therein.  Otherwise, a new array is allocated with the
500 +     * runtime type of the specified array and the size of this queue.
501 +     *
502 +     * <p>If this queue fits in the specified array with room to spare
503 +     * (i.e., the array has more elements than this queue), the element in
504 +     * the array immediately following the end of the queue is set to
505 +     * <tt>null</tt>.
506 +     *
507 +     * <p>Like the {@link #toArray()} method, this method acts as bridge between
508 +     * array-based and collection-based APIs.  Further, this method allows
509 +     * precise control over the runtime type of the output array, and may,
510 +     * under certain circumstances, be used to save allocation costs.
511 +     *
512 +     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
513 +     * The following code can be used to dump the queue into a newly
514 +     * allocated array of <tt>String</tt>:
515 +     *
516 +     * <pre>
517 +     *     String[] y = x.toArray(new String[0]);</pre>
518 +     *
519 +     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
520 +     * <tt>toArray()</tt>.
521 +     *
522 +     * @param a the array into which the elements of the queue are to
523 +     *          be stored, if it is big enough; otherwise, a new array of the
524 +     *          same runtime type is allocated for this purpose
525 +     * @return an array containing all of the elements in this queue
526 +     * @throws ArrayStoreException if the runtime type of the specified array
527 +     *         is not a supertype of the runtime type of every element in
528 +     *         this queue
529 +     * @throws NullPointerException if the specified array is null
530 +     */
531      public <T> T[] toArray(T[] a) {
532          final E[] items = this.items;
533          final ReentrantLock lock = this.lock;
# Line 488 | Line 563 | public class ArrayBlockingQueue<E> exten
563          }
564      }
565  
491
566      /**
567       * Atomically removes all of the elements from this queue.
568       * The queue will be empty after this call returns.
# Line 513 | Line 587 | public class ArrayBlockingQueue<E> exten
587          }
588      }
589  
590 +    /**
591 +     * @throws UnsupportedOperationException {@inheritDoc}
592 +     * @throws ClassCastException            {@inheritDoc}
593 +     * @throws NullPointerException          {@inheritDoc}
594 +     * @throws IllegalArgumentException      {@inheritDoc}
595 +     */
596      public int drainTo(Collection<? super E> c) {
597          if (c == null)
598              throw new NullPointerException();
# Line 543 | Line 623 | public class ArrayBlockingQueue<E> exten
623          }
624      }
625  
626 <
626 >    /**
627 >     * @throws UnsupportedOperationException {@inheritDoc}
628 >     * @throws ClassCastException            {@inheritDoc}
629 >     * @throws NullPointerException          {@inheritDoc}
630 >     * @throws IllegalArgumentException      {@inheritDoc}
631 >     */
632      public int drainTo(Collection<? super E> c, int maxElements) {
633          if (c == null)
634              throw new NullPointerException();
# Line 585 | Line 670 | public class ArrayBlockingQueue<E> exten
670       * construction of the iterator, and may (but is not guaranteed to)
671       * reflect any modifications subsequent to construction.
672       *
673 <     * @return an iterator over the elements in this queue in proper sequence.
673 >     * @return an iterator over the elements in this queue in proper sequence
674       */
675      public Iterator<E> iterator() {
676          final ReentrantLock lock = this.lock;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines