ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java
Revision: 1.32
Committed: Sat Oct 18 12:29:33 2003 UTC (20 years, 7 months ago) by dl
Branch: MAIN
Changes since 1.31: +1 -0 lines
Log Message:
Added docs for type params

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 dl 1.11 import java.util.concurrent.locks.*;
9 tim 1.1 import java.util.*;
10    
11     /**
12 dl 1.25 * A bounded {@linkplain BlockingQueue blocking queue} backed by an
13     * array. This queue orders elements FIFO (first-in-first-out). The
14     * <em>head</em> of the queue is that element that has been on the
15     * queue the longest time. The <em>tail</em> of the queue is that
16     * element that has been on the queue the shortest time. New elements
17     * are inserted at the tail of the queue, and the queue retrieval
18     * operations obtain elements at the head of the queue.
19 dholmes 1.13 *
20 tim 1.15 * <p>This is a classic &quot;bounded buffer&quot;, in which a fixed-sized
21 dholmes 1.13 * array holds
22 dl 1.11 * elements inserted by producers and extracted by consumers. Once
23     * created, the capacity can not be increased. Attempts to offer an
24     * element to a full queue will result in the offer operation
25     * blocking; attempts to retrieve an element from an empty queue will
26 tim 1.12 * similarly block.
27 dl 1.11 *
28     * <p> This class supports an optional fairness policy for ordering
29     * threads blocked on an insertion or removal. By default, this
30     * ordering is not guaranteed. However, an <tt>ArrayBlockingQueue</tt>
31     * constructed with fairness set to <tt>true</tt> grants blocked
32 dl 1.25 * threads access in FIFO order. Fairness generally decreases
33 dl 1.29 * throughput but reduces variability and avoids starvation.
34 brian 1.7 *
35 dl 1.26 * <p>This class implements all of the <em>optional</em> methods
36     * of the {@link Collection} and {@link Iterator} interfaces.
37     *
38 dl 1.8 * @since 1.5
39     * @author Doug Lea
40 dl 1.32 * @param <E> the base class of all elements held in this collection
41 dl 1.8 */
42 dl 1.5 public class ArrayBlockingQueue<E> extends AbstractQueue<E>
43 tim 1.1 implements BlockingQueue<E>, java.io.Serializable {
44 dl 1.24 private static final long serialVersionUID = -817911632652898425L;
45 tim 1.1
46 dl 1.8 /** The queued items */
47 tim 1.12 private transient final E[] items;
48 dl 1.8 /** items index for next take, poll or remove */
49 tim 1.12 private transient int takeIndex;
50 dl 1.8 /** items index for next put, offer, or add. */
51 tim 1.12 private transient int putIndex;
52 dl 1.8 /** Number of items in the queue */
53 dl 1.5 private int count;
54 tim 1.12
55 dl 1.5 /**
56     * An array used only during deserialization, to hold
57     * items read back in from the stream, and then used
58     * as "items" by readResolve via the private constructor.
59     */
60     private transient E[] deserializedItems;
61 tim 1.12
62 dl 1.5 /*
63     * Concurrency control via the classic two-condition algorithm
64     * found in any textbook.
65     */
66    
67 dl 1.11 /** Main lock guarding all access */
68     private final ReentrantLock lock;
69 dholmes 1.13 /** Condition for waiting takes */
70 dl 1.31 private final ReentrantLock.ConditionObject notEmpty;
71 dl 1.8 /** Condition for wiating puts */
72 dl 1.31 private final ReentrantLock.ConditionObject notFull;
73 dl 1.5
74     // Internal helper methods
75    
76     /**
77     * Circularly increment i.
78     */
79     int inc(int i) {
80     return (++i == items.length)? 0 : i;
81     }
82    
83     /**
84 dl 1.9 * Insert element at current put position, advance, and signal.
85     * Call only when holding lock.
86 dl 1.5 */
87     private void insert(E x) {
88     items[putIndex] = x;
89     putIndex = inc(putIndex);
90     ++count;
91 dl 1.9 notEmpty.signal();
92 tim 1.1 }
93 tim 1.12
94 dl 1.5 /**
95 dl 1.9 * Extract element at current take position, advance, and signal.
96     * Call only when holding lock.
97 dl 1.5 */
98 dholmes 1.13 private E extract() {
99 dl 1.5 E x = items[takeIndex];
100     items[takeIndex] = null;
101     takeIndex = inc(takeIndex);
102     --count;
103 dl 1.9 notFull.signal();
104 dl 1.5 return x;
105     }
106    
107     /**
108 tim 1.12 * Utility for remove and iterator.remove: Delete item at position i.
109 dl 1.9 * Call only when holding lock.
110 dl 1.5 */
111     void removeAt(int i) {
112 dl 1.9 // if removing front item, just advance
113     if (i == takeIndex) {
114     items[takeIndex] = null;
115     takeIndex = inc(takeIndex);
116 tim 1.23 } else {
117 dl 1.9 // slide over all others up through putIndex.
118     for (;;) {
119     int nexti = inc(i);
120     if (nexti != putIndex) {
121     items[i] = items[nexti];
122     i = nexti;
123 tim 1.23 } else {
124 dl 1.9 items[i] = null;
125     putIndex = i;
126     break;
127     }
128 dl 1.5 }
129     }
130 dl 1.9 --count;
131     notFull.signal();
132 tim 1.1 }
133    
134     /**
135 tim 1.12 * Internal constructor also used by readResolve.
136 dl 1.5 * Sets all final fields, plus count.
137 tim 1.15 * @param cap the capacity
138 dl 1.5 * @param array the array to use or null if should create new one
139     * @param count the number of items in the array, where indices 0
140     * to count-1 hold items.
141 dholmes 1.16 * @param lk the lock to use with this queue
142 dl 1.5 */
143 tim 1.15 private ArrayBlockingQueue(int cap, E[] array, int count,
144 dholmes 1.13 ReentrantLock lk) {
145 tim 1.15 if (cap <= 0)
146 dl 1.5 throw new IllegalArgumentException();
147     if (array == null)
148 tim 1.12 this.items = (E[]) new Object[cap];
149 dl 1.5 else
150     this.items = array;
151     this.putIndex = count;
152     this.count = count;
153 dl 1.11 lock = lk;
154     notEmpty = lock.newCondition();
155     notFull = lock.newCondition();
156 dl 1.5 }
157 tim 1.12
158 dl 1.5 /**
159 dholmes 1.21 * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
160 dholmes 1.13 * capacity and default access policy.
161     * @param capacity the capacity of this queue
162 dholmes 1.16 * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
163 dl 1.5 */
164 dholmes 1.13 public ArrayBlockingQueue(int capacity) {
165     this(capacity, null, 0, new ReentrantLock());
166 dl 1.5 }
167 dl 1.2
168 dl 1.5 /**
169 dholmes 1.21 * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
170 dholmes 1.13 * capacity and the specified access policy.
171     * @param capacity the capacity of this queue
172     * @param fair if <tt>true</tt> then queue accesses for threads blocked
173     * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
174     * the access order is unspecified.
175 dholmes 1.16 * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
176 dl 1.11 */
177 dholmes 1.13 public ArrayBlockingQueue(int capacity, boolean fair) {
178     this(capacity, null, 0, new ReentrantLock(fair));
179 dl 1.5 }
180    
181 dholmes 1.16 /**
182 dholmes 1.21 * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
183     * capacity, the specified access policy and initially containing the
184 tim 1.17 * elements of the given collection,
185 dholmes 1.16 * added in traversal order of the collection's iterator.
186     * @param capacity the capacity of this queue
187     * @param fair if <tt>true</tt> then queue accesses for threads blocked
188     * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
189     * the access order is unspecified.
190     * @param c the collection of elements to initially contain
191     * @throws IllegalArgumentException if <tt>capacity</tt> is less than
192     * <tt>c.size()</tt>, or less than 1.
193     * @throws NullPointerException if <tt>c</tt> or any element within it
194     * is <tt>null</tt>
195     */
196 tim 1.20 public ArrayBlockingQueue(int capacity, boolean fair,
197 dholmes 1.18 Collection<? extends E> c) {
198 dholmes 1.16 this(capacity, null, 0, new ReentrantLock(fair));
199    
200     if (capacity < c.size())
201     throw new IllegalArgumentException();
202    
203 tim 1.20 for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
204     add(it.next());
205 dholmes 1.16 }
206 dl 1.2
207 dholmes 1.13 /**
208 dholmes 1.27 * Inserts the specified element at the tail of this queue if possible,
209     * returning immediately if this queue is full.
210 dl 1.25 *
211 dl 1.28 * @param o the element to add.
212     * @return <tt>true</tt> if it was possible to add the element to
213     * this queue, else <tt>false</tt>
214 dl 1.25 * @throws NullPointerException if the specified element is <tt>null</tt>
215 dholmes 1.13 */
216 dholmes 1.21 public boolean offer(E o) {
217     if (o == null) throw new NullPointerException();
218 dl 1.5 lock.lock();
219     try {
220 tim 1.12 if (count == items.length)
221 dl 1.2 return false;
222 dl 1.5 else {
223 dholmes 1.21 insert(o);
224 dl 1.5 return true;
225     }
226 tim 1.23 } finally {
227 tim 1.12 lock.unlock();
228 dl 1.2 }
229 dl 1.5 }
230 dl 1.2
231 dholmes 1.13 /**
232 dholmes 1.27 * Inserts the specified element at the tail of this queue, waiting if
233 dholmes 1.13 * necessary up to the specified wait time for space to become available.
234 dl 1.28 * @param o the element to add
235     * @param timeout how long to wait before giving up, in units of
236     * <tt>unit</tt>
237     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
238     * <tt>timeout</tt> parameter
239     * @return <tt>true</tt> if successful, or <tt>false</tt> if
240     * the specified waiting time elapses before space is available.
241     * @throws InterruptedException if interrupted while waiting.
242 dl 1.25 * @throws NullPointerException if the specified element is <tt>null</tt>.
243 brian 1.7 */
244 dholmes 1.21 public boolean offer(E o, long timeout, TimeUnit unit)
245 dholmes 1.13 throws InterruptedException {
246 dl 1.2
247 dholmes 1.21 if (o == null) throw new NullPointerException();
248 dholmes 1.13
249 dl 1.5 lock.lockInterruptibly();
250     try {
251 dholmes 1.13 long nanos = unit.toNanos(timeout);
252 dl 1.5 for (;;) {
253     if (count != items.length) {
254 dholmes 1.21 insert(o);
255 dl 1.5 return true;
256     }
257     if (nanos <= 0)
258     return false;
259     try {
260     nanos = notFull.awaitNanos(nanos);
261 tim 1.23 } catch (InterruptedException ie) {
262 dl 1.5 notFull.signal(); // propagate to non-interrupted thread
263     throw ie;
264     }
265     }
266 tim 1.23 } finally {
267 dl 1.5 lock.unlock();
268 dl 1.2 }
269 dl 1.5 }
270 dl 1.2
271 dholmes 1.13
272     public E poll() {
273     lock.lock();
274     try {
275     if (count == 0)
276     return null;
277     E x = extract();
278     return x;
279 tim 1.23 } finally {
280 tim 1.15 lock.unlock();
281 dholmes 1.13 }
282     }
283    
284 dl 1.5 public E poll(long timeout, TimeUnit unit) throws InterruptedException {
285     lock.lockInterruptibly();
286     try {
287 dholmes 1.13 long nanos = unit.toNanos(timeout);
288 dl 1.2 for (;;) {
289 dl 1.5 if (count != 0) {
290     E x = extract();
291     return x;
292 dl 1.2 }
293 dl 1.5 if (nanos <= 0)
294     return null;
295     try {
296     nanos = notEmpty.awaitNanos(nanos);
297 tim 1.23 } catch (InterruptedException ie) {
298 dl 1.5 notEmpty.signal(); // propagate to non-interrupted thread
299     throw ie;
300     }
301    
302 dl 1.2 }
303 tim 1.23 } finally {
304 dl 1.5 lock.unlock();
305     }
306     }
307 dl 1.2
308 brian 1.7
309 dholmes 1.21 public boolean remove(Object o) {
310     if (o == null) return false;
311 dl 1.5 lock.lock();
312     try {
313     int i = takeIndex;
314     int k = 0;
315     for (;;) {
316     if (k++ >= count)
317     return false;
318 dholmes 1.21 if (o.equals(items[i])) {
319 dl 1.5 removeAt(i);
320     return true;
321     }
322 dl 1.2 i = inc(i);
323 dl 1.5 }
324 tim 1.12
325 tim 1.23 } finally {
326 dl 1.5 lock.unlock();
327     }
328     }
329 brian 1.7
330 dholmes 1.13 public E peek() {
331     lock.lock();
332     try {
333     return (count == 0) ? null : items[takeIndex];
334 tim 1.23 } finally {
335 dholmes 1.13 lock.unlock();
336     }
337     }
338    
339     public E take() throws InterruptedException {
340     lock.lockInterruptibly();
341     try {
342     try {
343     while (count == 0)
344     notEmpty.await();
345 tim 1.23 } catch (InterruptedException ie) {
346 dholmes 1.13 notEmpty.signal(); // propagate to non-interrupted thread
347     throw ie;
348     }
349     E x = extract();
350     return x;
351 tim 1.23 } finally {
352 dholmes 1.13 lock.unlock();
353     }
354     }
355    
356     /**
357 dholmes 1.21 * Adds the specified element to the tail of this queue, waiting if
358 dholmes 1.13 * necessary for space to become available.
359 dl 1.28 * @param o the element to add
360     * @throws InterruptedException if interrupted while waiting.
361 dl 1.25 * @throws NullPointerException if the specified element is <tt>null</tt>.
362 dholmes 1.13 */
363 dholmes 1.21 public void put(E o) throws InterruptedException {
364 dholmes 1.13
365 dholmes 1.21 if (o == null) throw new NullPointerException();
366 dholmes 1.13
367     lock.lockInterruptibly();
368     try {
369     try {
370     while (count == items.length)
371     notFull.await();
372 tim 1.23 } catch (InterruptedException ie) {
373 dholmes 1.13 notFull.signal(); // propagate to non-interrupted thread
374     throw ie;
375     }
376 dholmes 1.21 insert(o);
377 tim 1.23 } finally {
378 dholmes 1.13 lock.unlock();
379     }
380     }
381    
382     // this doc comment is overridden to remove the reference to collections
383     // greater in size than Integer.MAX_VALUE
384 tim 1.15 /**
385 dl 1.25 * Returns the number of elements in this queue.
386     *
387     * @return the number of elements in this queue.
388 dholmes 1.13 */
389     public int size() {
390     lock.lock();
391     try {
392     return count;
393 tim 1.23 } finally {
394 dholmes 1.13 lock.unlock();
395     }
396     }
397    
398     // this doc comment is a modified copy of the inherited doc comment,
399     // without the reference to unlimited queues.
400 tim 1.15 /**
401 dholmes 1.21 * Returns the number of elements that this queue can ideally (in
402 dholmes 1.13 * the absence of memory or resource constraints) accept without
403     * blocking. This is always equal to the initial capacity of this queue
404     * less the current <tt>size</tt> of this queue.
405     * <p>Note that you <em>cannot</em> always tell if
406     * an attempt to <tt>add</tt> an element will succeed by
407     * inspecting <tt>remainingCapacity</tt> because it may be the
408     * case that a waiting consumer is ready to <tt>take</tt> an
409     * element out of an otherwise full queue.
410     */
411     public int remainingCapacity() {
412     lock.lock();
413     try {
414     return items.length - count;
415 tim 1.23 } finally {
416 dholmes 1.13 lock.unlock();
417     }
418     }
419    
420    
421 dholmes 1.21 public boolean contains(Object o) {
422     if (o == null) return false;
423 dl 1.5 lock.lock();
424     try {
425     int i = takeIndex;
426     int k = 0;
427     while (k++ < count) {
428 dholmes 1.21 if (o.equals(items[i]))
429 dl 1.2 return true;
430 dl 1.5 i = inc(i);
431     }
432 dl 1.2 return false;
433 tim 1.23 } finally {
434 dl 1.5 lock.unlock();
435     }
436     }
437 brian 1.7
438 dl 1.5 public Object[] toArray() {
439     lock.lock();
440     try {
441 tim 1.12 E[] a = (E[]) new Object[count];
442 dl 1.5 int k = 0;
443     int i = takeIndex;
444     while (k < count) {
445 dl 1.2 a[k++] = items[i];
446 dl 1.5 i = inc(i);
447     }
448 dl 1.2 return a;
449 tim 1.23 } finally {
450 dl 1.5 lock.unlock();
451     }
452     }
453 brian 1.7
454 dl 1.5 public <T> T[] toArray(T[] a) {
455     lock.lock();
456     try {
457     if (a.length < count)
458 dholmes 1.16 a = (T[])java.lang.reflect.Array.newInstance(
459 tim 1.17 a.getClass().getComponentType(),
460 dholmes 1.16 count
461     );
462 tim 1.12
463 dl 1.5 int k = 0;
464     int i = takeIndex;
465     while (k < count) {
466 dl 1.2 a[k++] = (T)items[i];
467 dl 1.5 i = inc(i);
468     }
469     if (a.length > count)
470     a[count] = null;
471 dl 1.2 return a;
472 tim 1.23 } finally {
473 dl 1.5 lock.unlock();
474     }
475     }
476 dl 1.6
477     public String toString() {
478     lock.lock();
479     try {
480     return super.toString();
481 tim 1.23 } finally {
482 dl 1.6 lock.unlock();
483     }
484     }
485 tim 1.12
486 dl 1.30
487     public void clear() {
488     lock.lock();
489     try {
490     int i = takeIndex;
491     int k = count;
492     while (k-- > 0) {
493     items[i] = null;
494     i = inc(i);
495     }
496     count = 0;
497     putIndex = 0;
498     takeIndex = 0;
499     notFull.signalAll();
500     } finally {
501     lock.unlock();
502     }
503     }
504    
505     public int drainTo(Collection<? super E> c) {
506     if (c == null)
507     throw new NullPointerException();
508     if (c == this)
509     throw new IllegalArgumentException();
510     lock.lock();
511     try {
512     int i = takeIndex;
513     int n = 0;
514     int max = count;
515     while (n < max) {
516     c.add(items[i]);
517     items[i] = null;
518     i = inc(i);
519     ++n;
520     }
521     if (n > 0) {
522     count = 0;
523     putIndex = 0;
524     takeIndex = 0;
525     notFull.signalAll();
526     }
527     return n;
528     } finally {
529     lock.unlock();
530     }
531     }
532    
533    
534     public int drainTo(Collection<? super E> c, int maxElements) {
535     if (c == null)
536     throw new NullPointerException();
537     if (c == this)
538     throw new IllegalArgumentException();
539     if (maxElements <= 0)
540     return 0;
541     lock.lock();
542     try {
543     int i = takeIndex;
544     int n = 0;
545     int sz = count;
546     int max = (maxElements < count)? maxElements : count;
547     while (n < max) {
548     c.add(items[i]);
549     items[i] = null;
550     i = inc(i);
551     ++n;
552     }
553     if (n > 0) {
554     count -= n;
555     takeIndex = i;
556     notFull.signalAll();
557     }
558     return n;
559     } finally {
560     lock.unlock();
561     }
562     }
563    
564    
565 brian 1.7 /**
566     * Returns an iterator over the elements in this queue in proper sequence.
567 dl 1.22 * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
568     * will never throw {@link java.util.ConcurrentModificationException},
569     * and guarantees to traverse elements as they existed upon
570     * construction of the iterator, and may (but is not guaranteed to)
571     * reflect any modifications subsequent to construction.
572 brian 1.7 *
573     * @return an iterator over the elements in this queue in proper sequence.
574     */
575 dl 1.5 public Iterator<E> iterator() {
576     lock.lock();
577     try {
578 dl 1.2 return new Itr();
579 tim 1.23 } finally {
580 dl 1.5 lock.unlock();
581     }
582     }
583 dl 1.8
584     /**
585     * Iterator for ArrayBlockingQueue
586     */
587 dl 1.5 private class Itr implements Iterator<E> {
588     /**
589     * Index of element to be returned by next,
590     * or a negative number if no such.
591     */
592 dl 1.8 private int nextIndex;
593 dl 1.2
594 tim 1.12 /**
595 dl 1.5 * nextItem holds on to item fields because once we claim
596     * that an element exists in hasNext(), we must return it in
597     * the following next() call even if it was in the process of
598     * being removed when hasNext() was called.
599     **/
600 dl 1.8 private E nextItem;
601 dl 1.5
602     /**
603     * Index of element returned by most recent call to next.
604     * Reset to -1 if this element is deleted by a call to remove.
605     */
606 dl 1.8 private int lastRet;
607 tim 1.12
608 dl 1.5 Itr() {
609     lastRet = -1;
610 tim 1.12 if (count == 0)
611 dl 1.5 nextIndex = -1;
612     else {
613     nextIndex = takeIndex;
614     nextItem = items[takeIndex];
615     }
616     }
617 tim 1.12
618 dl 1.5 public boolean hasNext() {
619     /*
620     * No sync. We can return true by mistake here
621     * only if this iterator passed across threads,
622     * which we don't support anyway.
623 dl 1.2 */
624 dl 1.5 return nextIndex >= 0;
625     }
626    
627     /**
628 dholmes 1.13 * Check whether nextIndex is valid; if so setting nextItem.
629 dl 1.5 * Stops iterator when either hits putIndex or sees null item.
630     */
631     private void checkNext() {
632     if (nextIndex == putIndex) {
633     nextIndex = -1;
634     nextItem = null;
635 tim 1.23 } else {
636 dl 1.5 nextItem = items[nextIndex];
637     if (nextItem == null)
638     nextIndex = -1;
639 dl 1.2 }
640 dl 1.5 }
641 tim 1.12
642 dl 1.5 public E next() {
643     lock.lock();
644     try {
645     if (nextIndex < 0)
646 dl 1.2 throw new NoSuchElementException();
647 dl 1.5 lastRet = nextIndex;
648     E x = nextItem;
649     nextIndex = inc(nextIndex);
650     checkNext();
651     return x;
652 tim 1.23 } finally {
653 tim 1.12 lock.unlock();
654 dl 1.2 }
655 dl 1.5 }
656 tim 1.12
657 dl 1.5 public void remove() {
658     lock.lock();
659     try {
660 dl 1.2 int i = lastRet;
661     if (i == -1)
662     throw new IllegalStateException();
663     lastRet = -1;
664 tim 1.12
665 dl 1.9 int ti = takeIndex;
666 dl 1.2 removeAt(i);
667 dl 1.9 // back up cursor (reset to front if was first element)
668 tim 1.12 nextIndex = (i == ti) ? takeIndex : i;
669 dl 1.5 checkNext();
670 tim 1.23 } finally {
671 dl 1.5 lock.unlock();
672     }
673     }
674     }
675 tim 1.12
676 dl 1.5 /**
677     * Save the state to a stream (that is, serialize it).
678     *
679     * @serialData The maximumSize is emitted (int), followed by all of
680     * its elements (each an <tt>E</tt>) in the proper order.
681 dl 1.8 * @param s the stream
682 dl 1.5 */
683     private void writeObject(java.io.ObjectOutputStream s)
684     throws java.io.IOException {
685 tim 1.12
686 dl 1.5 // Write out element count, and any hidden stuff
687     s.defaultWriteObject();
688     // Write out maximumSize == items length
689     s.writeInt(items.length);
690 tim 1.12
691 dl 1.5 // Write out all elements in the proper order.
692     int i = takeIndex;
693     int k = 0;
694     while (k++ < count) {
695     s.writeObject(items[i]);
696     i = inc(i);
697 dl 1.2 }
698 dl 1.5 }
699 tim 1.12
700 dl 1.5 /**
701 dholmes 1.13 * Reconstitute this queue instance from a stream (that is,
702 dl 1.5 * deserialize it).
703 dl 1.8 * @param s the stream
704 dl 1.5 */
705     private void readObject(java.io.ObjectInputStream s)
706     throws java.io.IOException, ClassNotFoundException {
707     // Read in size, and any hidden stuff
708     s.defaultReadObject();
709     int size = count;
710 tim 1.12
711 dl 1.5 // Read in array length and allocate array
712     int arrayLength = s.readInt();
713 tim 1.12
714 dl 1.5 // We use deserializedItems here because "items" is final
715 tim 1.12 deserializedItems = (E[]) new Object[arrayLength];
716    
717 dl 1.5 // Read in all elements in the proper order into deserializedItems
718     for (int i = 0; i < size; i++)
719     deserializedItems[i] = (E)s.readObject();
720     }
721 tim 1.12
722 dl 1.5 /**
723     * Throw away the object created with readObject, and replace it
724     * with a usable ArrayBlockingQueue.
725 dl 1.8 * @return the ArrayBlockingQueue
726 dl 1.5 */
727     private Object readResolve() throws java.io.ObjectStreamException {
728     E[] array = deserializedItems;
729     deserializedItems = null;
730 tim 1.17 return new ArrayBlockingQueue<E>(array.length, array, count, lock);
731 tim 1.1 }
732     }