blob: 48fc8717a42193ed75e45dd7335906307eaa6e7c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Sun designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Sun in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 */
24
25/*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/licenses/publicdomain
34 */
35
36package java.util.concurrent;
37import java.util.*;
38import java.util.concurrent.locks.*;
39
40/**
41 * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
42 * linked nodes.
43 *
44 * <p> The optional capacity bound constructor argument serves as a
45 * way to prevent excessive expansion. The capacity, if unspecified,
46 * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
47 * dynamically created upon each insertion unless this would bring the
48 * deque above capacity.
49 *
50 * <p>Most operations run in constant time (ignoring time spent
51 * blocking). Exceptions include {@link #remove(Object) remove},
52 * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link
53 * #removeLastOccurrence removeLastOccurrence}, {@link #contains
54 * contains}, {@link #iterator iterator.remove()}, and the bulk
55 * operations, all of which run in linear time.
56 *
57 * <p>This class and its iterator implement all of the
58 * <em>optional</em> methods of the {@link Collection} and {@link
59 * Iterator} interfaces.
60 *
61 * <p>This class is a member of the
62 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
63 * Java Collections Framework</a>.
64 *
65 * @since 1.6
66 * @author Doug Lea
67 * @param <E> the type of elements held in this collection
68 */
69public class LinkedBlockingDeque<E>
70 extends AbstractQueue<E>
71 implements BlockingDeque<E>, java.io.Serializable {
72
73 /*
74 * Implemented as a simple doubly-linked list protected by a
75 * single lock and using conditions to manage blocking.
76 */
77
78 /*
79 * We have "diamond" multiple interface/abstract class inheritance
80 * here, and that introduces ambiguities. Often we want the
81 * BlockingDeque javadoc combined with the AbstractQueue
82 * implementation, so a lot of method specs are duplicated here.
83 */
84
85 private static final long serialVersionUID = -387911632671998426L;
86
87 /** Doubly-linked list node class */
88 static final class Node<E> {
89 E item;
90 Node<E> prev;
91 Node<E> next;
92 Node(E x, Node<E> p, Node<E> n) {
93 item = x;
94 prev = p;
95 next = n;
96 }
97 }
98
99 /** Pointer to first node */
100 private transient Node<E> first;
101 /** Pointer to last node */
102 private transient Node<E> last;
103 /** Number of items in the deque */
104 private transient int count;
105 /** Maximum number of items in the deque */
106 private final int capacity;
107 /** Main lock guarding all access */
108 private final ReentrantLock lock = new ReentrantLock();
109 /** Condition for waiting takes */
110 private final Condition notEmpty = lock.newCondition();
111 /** Condition for waiting puts */
112 private final Condition notFull = lock.newCondition();
113
114 /**
115 * Creates a <tt>LinkedBlockingDeque</tt> with a capacity of
116 * {@link Integer#MAX_VALUE}.
117 */
118 public LinkedBlockingDeque() {
119 this(Integer.MAX_VALUE);
120 }
121
122 /**
123 * Creates a <tt>LinkedBlockingDeque</tt> with the given (fixed) capacity.
124 *
125 * @param capacity the capacity of this deque
126 * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
127 */
128 public LinkedBlockingDeque(int capacity) {
129 if (capacity <= 0) throw new IllegalArgumentException();
130 this.capacity = capacity;
131 }
132
133 /**
134 * Creates a <tt>LinkedBlockingDeque</tt> with a capacity of
135 * {@link Integer#MAX_VALUE}, initially containing the elements of
136 * the given collection, added in traversal order of the
137 * collection's iterator.
138 *
139 * @param c the collection of elements to initially contain
140 * @throws NullPointerException if the specified collection or any
141 * of its elements are null
142 */
143 public LinkedBlockingDeque(Collection<? extends E> c) {
144 this(Integer.MAX_VALUE);
145 for (E e : c)
146 add(e);
147 }
148
149
150 // Basic linking and unlinking operations, called only while holding lock
151
152 /**
153 * Links e as first element, or returns false if full.
154 */
155 private boolean linkFirst(E e) {
156 if (count >= capacity)
157 return false;
158 ++count;
159 Node<E> f = first;
160 Node<E> x = new Node<E>(e, null, f);
161 first = x;
162 if (last == null)
163 last = x;
164 else
165 f.prev = x;
166 notEmpty.signal();
167 return true;
168 }
169
170 /**
171 * Links e as last element, or returns false if full.
172 */
173 private boolean linkLast(E e) {
174 if (count >= capacity)
175 return false;
176 ++count;
177 Node<E> l = last;
178 Node<E> x = new Node<E>(e, l, null);
179 last = x;
180 if (first == null)
181 first = x;
182 else
183 l.next = x;
184 notEmpty.signal();
185 return true;
186 }
187
188 /**
189 * Removes and returns first element, or null if empty.
190 */
191 private E unlinkFirst() {
192 Node<E> f = first;
193 if (f == null)
194 return null;
195 Node<E> n = f.next;
196 first = n;
197 if (n == null)
198 last = null;
199 else
200 n.prev = null;
201 --count;
202 notFull.signal();
203 return f.item;
204 }
205
206 /**
207 * Removes and returns last element, or null if empty.
208 */
209 private E unlinkLast() {
210 Node<E> l = last;
211 if (l == null)
212 return null;
213 Node<E> p = l.prev;
214 last = p;
215 if (p == null)
216 first = null;
217 else
218 p.next = null;
219 --count;
220 notFull.signal();
221 return l.item;
222 }
223
224 /**
225 * Unlink e
226 */
227 private void unlink(Node<E> x) {
228 Node<E> p = x.prev;
229 Node<E> n = x.next;
230 if (p == null) {
231 if (n == null)
232 first = last = null;
233 else {
234 n.prev = null;
235 first = n;
236 }
237 } else if (n == null) {
238 p.next = null;
239 last = p;
240 } else {
241 p.next = n;
242 n.prev = p;
243 }
244 --count;
245 notFull.signalAll();
246 }
247
248 // BlockingDeque methods
249
250 /**
251 * @throws IllegalStateException {@inheritDoc}
252 * @throws NullPointerException {@inheritDoc}
253 */
254 public void addFirst(E e) {
255 if (!offerFirst(e))
256 throw new IllegalStateException("Deque full");
257 }
258
259 /**
260 * @throws IllegalStateException {@inheritDoc}
261 * @throws NullPointerException {@inheritDoc}
262 */
263 public void addLast(E e) {
264 if (!offerLast(e))
265 throw new IllegalStateException("Deque full");
266 }
267
268 /**
269 * @throws NullPointerException {@inheritDoc}
270 */
271 public boolean offerFirst(E e) {
272 if (e == null) throw new NullPointerException();
273 lock.lock();
274 try {
275 return linkFirst(e);
276 } finally {
277 lock.unlock();
278 }
279 }
280
281 /**
282 * @throws NullPointerException {@inheritDoc}
283 */
284 public boolean offerLast(E e) {
285 if (e == null) throw new NullPointerException();
286 lock.lock();
287 try {
288 return linkLast(e);
289 } finally {
290 lock.unlock();
291 }
292 }
293
294 /**
295 * @throws NullPointerException {@inheritDoc}
296 * @throws InterruptedException {@inheritDoc}
297 */
298 public void putFirst(E e) throws InterruptedException {
299 if (e == null) throw new NullPointerException();
300 lock.lock();
301 try {
302 while (!linkFirst(e))
303 notFull.await();
304 } finally {
305 lock.unlock();
306 }
307 }
308
309 /**
310 * @throws NullPointerException {@inheritDoc}
311 * @throws InterruptedException {@inheritDoc}
312 */
313 public void putLast(E e) throws InterruptedException {
314 if (e == null) throw new NullPointerException();
315 lock.lock();
316 try {
317 while (!linkLast(e))
318 notFull.await();
319 } finally {
320 lock.unlock();
321 }
322 }
323
324 /**
325 * @throws NullPointerException {@inheritDoc}
326 * @throws InterruptedException {@inheritDoc}
327 */
328 public boolean offerFirst(E e, long timeout, TimeUnit unit)
329 throws InterruptedException {
330 if (e == null) throw new NullPointerException();
331 long nanos = unit.toNanos(timeout);
332 lock.lockInterruptibly();
333 try {
334 for (;;) {
335 if (linkFirst(e))
336 return true;
337 if (nanos <= 0)
338 return false;
339 nanos = notFull.awaitNanos(nanos);
340 }
341 } finally {
342 lock.unlock();
343 }
344 }
345
346 /**
347 * @throws NullPointerException {@inheritDoc}
348 * @throws InterruptedException {@inheritDoc}
349 */
350 public boolean offerLast(E e, long timeout, TimeUnit unit)
351 throws InterruptedException {
352 if (e == null) throw new NullPointerException();
353 long nanos = unit.toNanos(timeout);
354 lock.lockInterruptibly();
355 try {
356 for (;;) {
357 if (linkLast(e))
358 return true;
359 if (nanos <= 0)
360 return false;
361 nanos = notFull.awaitNanos(nanos);
362 }
363 } finally {
364 lock.unlock();
365 }
366 }
367
368 /**
369 * @throws NoSuchElementException {@inheritDoc}
370 */
371 public E removeFirst() {
372 E x = pollFirst();
373 if (x == null) throw new NoSuchElementException();
374 return x;
375 }
376
377 /**
378 * @throws NoSuchElementException {@inheritDoc}
379 */
380 public E removeLast() {
381 E x = pollLast();
382 if (x == null) throw new NoSuchElementException();
383 return x;
384 }
385
386 public E pollFirst() {
387 lock.lock();
388 try {
389 return unlinkFirst();
390 } finally {
391 lock.unlock();
392 }
393 }
394
395 public E pollLast() {
396 lock.lock();
397 try {
398 return unlinkLast();
399 } finally {
400 lock.unlock();
401 }
402 }
403
404 public E takeFirst() throws InterruptedException {
405 lock.lock();
406 try {
407 E x;
408 while ( (x = unlinkFirst()) == null)
409 notEmpty.await();
410 return x;
411 } finally {
412 lock.unlock();
413 }
414 }
415
416 public E takeLast() throws InterruptedException {
417 lock.lock();
418 try {
419 E x;
420 while ( (x = unlinkLast()) == null)
421 notEmpty.await();
422 return x;
423 } finally {
424 lock.unlock();
425 }
426 }
427
428 public E pollFirst(long timeout, TimeUnit unit)
429 throws InterruptedException {
430 long nanos = unit.toNanos(timeout);
431 lock.lockInterruptibly();
432 try {
433 for (;;) {
434 E x = unlinkFirst();
435 if (x != null)
436 return x;
437 if (nanos <= 0)
438 return null;
439 nanos = notEmpty.awaitNanos(nanos);
440 }
441 } finally {
442 lock.unlock();
443 }
444 }
445
446 public E pollLast(long timeout, TimeUnit unit)
447 throws InterruptedException {
448 long nanos = unit.toNanos(timeout);
449 lock.lockInterruptibly();
450 try {
451 for (;;) {
452 E x = unlinkLast();
453 if (x != null)
454 return x;
455 if (nanos <= 0)
456 return null;
457 nanos = notEmpty.awaitNanos(nanos);
458 }
459 } finally {
460 lock.unlock();
461 }
462 }
463
464 /**
465 * @throws NoSuchElementException {@inheritDoc}
466 */
467 public E getFirst() {
468 E x = peekFirst();
469 if (x == null) throw new NoSuchElementException();
470 return x;
471 }
472
473 /**
474 * @throws NoSuchElementException {@inheritDoc}
475 */
476 public E getLast() {
477 E x = peekLast();
478 if (x == null) throw new NoSuchElementException();
479 return x;
480 }
481
482 public E peekFirst() {
483 lock.lock();
484 try {
485 return (first == null) ? null : first.item;
486 } finally {
487 lock.unlock();
488 }
489 }
490
491 public E peekLast() {
492 lock.lock();
493 try {
494 return (last == null) ? null : last.item;
495 } finally {
496 lock.unlock();
497 }
498 }
499
500 public boolean removeFirstOccurrence(Object o) {
501 if (o == null) return false;
502 lock.lock();
503 try {
504 for (Node<E> p = first; p != null; p = p.next) {
505 if (o.equals(p.item)) {
506 unlink(p);
507 return true;
508 }
509 }
510 return false;
511 } finally {
512 lock.unlock();
513 }
514 }
515
516 public boolean removeLastOccurrence(Object o) {
517 if (o == null) return false;
518 lock.lock();
519 try {
520 for (Node<E> p = last; p != null; p = p.prev) {
521 if (o.equals(p.item)) {
522 unlink(p);
523 return true;
524 }
525 }
526 return false;
527 } finally {
528 lock.unlock();
529 }
530 }
531
532 // BlockingQueue methods
533
534 /**
535 * Inserts the specified element at the end of this deque unless it would
536 * violate capacity restrictions. When using a capacity-restricted deque,
537 * it is generally preferable to use method {@link #offer(Object) offer}.
538 *
539 * <p>This method is equivalent to {@link #addLast}.
540 *
541 * @throws IllegalStateException if the element cannot be added at this
542 * time due to capacity restrictions
543 * @throws NullPointerException if the specified element is null
544 */
545 public boolean add(E e) {
546 addLast(e);
547 return true;
548 }
549
550 /**
551 * @throws NullPointerException if the specified element is null
552 */
553 public boolean offer(E e) {
554 return offerLast(e);
555 }
556
557 /**
558 * @throws NullPointerException {@inheritDoc}
559 * @throws InterruptedException {@inheritDoc}
560 */
561 public void put(E e) throws InterruptedException {
562 putLast(e);
563 }
564
565 /**
566 * @throws NullPointerException {@inheritDoc}
567 * @throws InterruptedException {@inheritDoc}
568 */
569 public boolean offer(E e, long timeout, TimeUnit unit)
570 throws InterruptedException {
571 return offerLast(e, timeout, unit);
572 }
573
574 /**
575 * Retrieves and removes the head of the queue represented by this deque.
576 * This method differs from {@link #poll poll} only in that it throws an
577 * exception if this deque is empty.
578 *
579 * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
580 *
581 * @return the head of the queue represented by this deque
582 * @throws NoSuchElementException if this deque is empty
583 */
584 public E remove() {
585 return removeFirst();
586 }
587
588 public E poll() {
589 return pollFirst();
590 }
591
592 public E take() throws InterruptedException {
593 return takeFirst();
594 }
595
596 public E poll(long timeout, TimeUnit unit) throws InterruptedException {
597 return pollFirst(timeout, unit);
598 }
599
600 /**
601 * Retrieves, but does not remove, the head of the queue represented by
602 * this deque. This method differs from {@link #peek peek} only in that
603 * it throws an exception if this deque is empty.
604 *
605 * <p>This method is equivalent to {@link #getFirst() getFirst}.
606 *
607 * @return the head of the queue represented by this deque
608 * @throws NoSuchElementException if this deque is empty
609 */
610 public E element() {
611 return getFirst();
612 }
613
614 public E peek() {
615 return peekFirst();
616 }
617
618 /**
619 * Returns the number of additional elements that this deque can ideally
620 * (in the absence of memory or resource constraints) accept without
621 * blocking. This is always equal to the initial capacity of this deque
622 * less the current <tt>size</tt> of this deque.
623 *
624 * <p>Note that you <em>cannot</em> always tell if an attempt to insert
625 * an element will succeed by inspecting <tt>remainingCapacity</tt>
626 * because it may be the case that another thread is about to
627 * insert or remove an element.
628 */
629 public int remainingCapacity() {
630 lock.lock();
631 try {
632 return capacity - count;
633 } finally {
634 lock.unlock();
635 }
636 }
637
638 /**
639 * @throws UnsupportedOperationException {@inheritDoc}
640 * @throws ClassCastException {@inheritDoc}
641 * @throws NullPointerException {@inheritDoc}
642 * @throws IllegalArgumentException {@inheritDoc}
643 */
644 public int drainTo(Collection<? super E> c) {
645 if (c == null)
646 throw new NullPointerException();
647 if (c == this)
648 throw new IllegalArgumentException();
649 lock.lock();
650 try {
651 for (Node<E> p = first; p != null; p = p.next)
652 c.add(p.item);
653 int n = count;
654 count = 0;
655 first = last = null;
656 notFull.signalAll();
657 return n;
658 } finally {
659 lock.unlock();
660 }
661 }
662
663 /**
664 * @throws UnsupportedOperationException {@inheritDoc}
665 * @throws ClassCastException {@inheritDoc}
666 * @throws NullPointerException {@inheritDoc}
667 * @throws IllegalArgumentException {@inheritDoc}
668 */
669 public int drainTo(Collection<? super E> c, int maxElements) {
670 if (c == null)
671 throw new NullPointerException();
672 if (c == this)
673 throw new IllegalArgumentException();
674 lock.lock();
675 try {
676 int n = 0;
677 while (n < maxElements && first != null) {
678 c.add(first.item);
679 first.prev = null;
680 first = first.next;
681 --count;
682 ++n;
683 }
684 if (first == null)
685 last = null;
686 notFull.signalAll();
687 return n;
688 } finally {
689 lock.unlock();
690 }
691 }
692
693 // Stack methods
694
695 /**
696 * @throws IllegalStateException {@inheritDoc}
697 * @throws NullPointerException {@inheritDoc}
698 */
699 public void push(E e) {
700 addFirst(e);
701 }
702
703 /**
704 * @throws NoSuchElementException {@inheritDoc}
705 */
706 public E pop() {
707 return removeFirst();
708 }
709
710 // Collection methods
711
712 /**
713 * Removes the first occurrence of the specified element from this deque.
714 * If the deque does not contain the element, it is unchanged.
715 * More formally, removes the first element <tt>e</tt> such that
716 * <tt>o.equals(e)</tt> (if such an element exists).
717 * Returns <tt>true</tt> if this deque contained the specified element
718 * (or equivalently, if this deque changed as a result of the call).
719 *
720 * <p>This method is equivalent to
721 * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
722 *
723 * @param o element to be removed from this deque, if present
724 * @return <tt>true</tt> if this deque changed as a result of the call
725 */
726 public boolean remove(Object o) {
727 return removeFirstOccurrence(o);
728 }
729
730 /**
731 * Returns the number of elements in this deque.
732 *
733 * @return the number of elements in this deque
734 */
735 public int size() {
736 lock.lock();
737 try {
738 return count;
739 } finally {
740 lock.unlock();
741 }
742 }
743
744 /**
745 * Returns <tt>true</tt> if this deque contains the specified element.
746 * More formally, returns <tt>true</tt> if and only if this deque contains
747 * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
748 *
749 * @param o object to be checked for containment in this deque
750 * @return <tt>true</tt> if this deque contains the specified element
751 */
752 public boolean contains(Object o) {
753 if (o == null) return false;
754 lock.lock();
755 try {
756 for (Node<E> p = first; p != null; p = p.next)
757 if (o.equals(p.item))
758 return true;
759 return false;
760 } finally {
761 lock.unlock();
762 }
763 }
764
765 /**
766 * Variant of removeFirstOccurrence needed by iterator.remove.
767 * Searches for the node, not its contents.
768 */
769 boolean removeNode(Node<E> e) {
770 lock.lock();
771 try {
772 for (Node<E> p = first; p != null; p = p.next) {
773 if (p == e) {
774 unlink(p);
775 return true;
776 }
777 }
778 return false;
779 } finally {
780 lock.unlock();
781 }
782 }
783
784 /**
785 * Returns an array containing all of the elements in this deque, in
786 * proper sequence (from first to last element).
787 *
788 * <p>The returned array will be "safe" in that no references to it are
789 * maintained by this deque. (In other words, this method must allocate
790 * a new array). The caller is thus free to modify the returned array.
791 *
792 * <p>This method acts as bridge between array-based and collection-based
793 * APIs.
794 *
795 * @return an array containing all of the elements in this deque
796 */
797 public Object[] toArray() {
798 lock.lock();
799 try {
800 Object[] a = new Object[count];
801 int k = 0;
802 for (Node<E> p = first; p != null; p = p.next)
803 a[k++] = p.item;
804 return a;
805 } finally {
806 lock.unlock();
807 }
808 }
809
810 /**
811 * Returns an array containing all of the elements in this deque, in
812 * proper sequence; the runtime type of the returned array is that of
813 * the specified array. If the deque fits in the specified array, it
814 * is returned therein. Otherwise, a new array is allocated with the
815 * runtime type of the specified array and the size of this deque.
816 *
817 * <p>If this deque fits in the specified array with room to spare
818 * (i.e., the array has more elements than this deque), the element in
819 * the array immediately following the end of the deque is set to
820 * <tt>null</tt>.
821 *
822 * <p>Like the {@link #toArray()} method, this method acts as bridge between
823 * array-based and collection-based APIs. Further, this method allows
824 * precise control over the runtime type of the output array, and may,
825 * under certain circumstances, be used to save allocation costs.
826 *
827 * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
828 * The following code can be used to dump the deque into a newly
829 * allocated array of <tt>String</tt>:
830 *
831 * <pre>
832 * String[] y = x.toArray(new String[0]);</pre>
833 *
834 * Note that <tt>toArray(new Object[0])</tt> is identical in function to
835 * <tt>toArray()</tt>.
836 *
837 * @param a the array into which the elements of the deque are to
838 * be stored, if it is big enough; otherwise, a new array of the
839 * same runtime type is allocated for this purpose
840 * @return an array containing all of the elements in this deque
841 * @throws ArrayStoreException if the runtime type of the specified array
842 * is not a supertype of the runtime type of every element in
843 * this deque
844 * @throws NullPointerException if the specified array is null
845 */
846 public <T> T[] toArray(T[] a) {
847 lock.lock();
848 try {
849 if (a.length < count)
850 a = (T[])java.lang.reflect.Array.newInstance(
851 a.getClass().getComponentType(),
852 count
853 );
854
855 int k = 0;
856 for (Node<E> p = first; p != null; p = p.next)
857 a[k++] = (T)p.item;
858 if (a.length > k)
859 a[k] = null;
860 return a;
861 } finally {
862 lock.unlock();
863 }
864 }
865
866 public String toString() {
867 lock.lock();
868 try {
869 return super.toString();
870 } finally {
871 lock.unlock();
872 }
873 }
874
875 /**
876 * Atomically removes all of the elements from this deque.
877 * The deque will be empty after this call returns.
878 */
879 public void clear() {
880 lock.lock();
881 try {
882 first = last = null;
883 count = 0;
884 notFull.signalAll();
885 } finally {
886 lock.unlock();
887 }
888 }
889
890 /**
891 * Returns an iterator over the elements in this deque in proper sequence.
892 * The elements will be returned in order from first (head) to last (tail).
893 * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
894 * will never throw {@link ConcurrentModificationException},
895 * and guarantees to traverse elements as they existed upon
896 * construction of the iterator, and may (but is not guaranteed to)
897 * reflect any modifications subsequent to construction.
898 *
899 * @return an iterator over the elements in this deque in proper sequence
900 */
901 public Iterator<E> iterator() {
902 return new Itr();
903 }
904
905 /**
906 * Returns an iterator over the elements in this deque in reverse
907 * sequential order. The elements will be returned in order from
908 * last (tail) to first (head).
909 * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
910 * will never throw {@link ConcurrentModificationException},
911 * and guarantees to traverse elements as they existed upon
912 * construction of the iterator, and may (but is not guaranteed to)
913 * reflect any modifications subsequent to construction.
914 */
915 public Iterator<E> descendingIterator() {
916 return new DescendingItr();
917 }
918
919 /**
920 * Base class for Iterators for LinkedBlockingDeque
921 */
922 private abstract class AbstractItr implements Iterator<E> {
923 /**
924 * The next node to return in next
925 */
926 Node<E> next;
927
928 /**
929 * nextItem holds on to item fields because once we claim that
930 * an element exists in hasNext(), we must return item read
931 * under lock (in advance()) even if it was in the process of
932 * being removed when hasNext() was called.
933 */
934 E nextItem;
935
936 /**
937 * Node returned by most recent call to next. Needed by remove.
938 * Reset to null if this element is deleted by a call to remove.
939 */
940 private Node<E> lastRet;
941
942 AbstractItr() {
943 advance(); // set to initial position
944 }
945
946 /**
947 * Advances next, or if not yet initialized, sets to first node.
948 * Implemented to move forward vs backward in the two subclasses.
949 */
950 abstract void advance();
951
952 public boolean hasNext() {
953 return next != null;
954 }
955
956 public E next() {
957 if (next == null)
958 throw new NoSuchElementException();
959 lastRet = next;
960 E x = nextItem;
961 advance();
962 return x;
963 }
964
965 public void remove() {
966 Node<E> n = lastRet;
967 if (n == null)
968 throw new IllegalStateException();
969 lastRet = null;
970 // Note: removeNode rescans looking for this node to make
971 // sure it was not already removed. Otherwise, trying to
972 // re-remove could corrupt list.
973 removeNode(n);
974 }
975 }
976
977 /** Forward iterator */
978 private class Itr extends AbstractItr {
979 void advance() {
980 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
981 lock.lock();
982 try {
983 next = (next == null)? first : next.next;
984 nextItem = (next == null)? null : next.item;
985 } finally {
986 lock.unlock();
987 }
988 }
989 }
990
991 /**
992 * Descending iterator for LinkedBlockingDeque
993 */
994 private class DescendingItr extends AbstractItr {
995 void advance() {
996 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
997 lock.lock();
998 try {
999 next = (next == null)? last : next.prev;
1000 nextItem = (next == null)? null : next.item;
1001 } finally {
1002 lock.unlock();
1003 }
1004 }
1005 }
1006
1007 /**
1008 * Save the state of this deque to a stream (that is, serialize it).
1009 *
1010 * @serialData The capacity (int), followed by elements (each an
1011 * <tt>Object</tt>) in the proper order, followed by a null
1012 * @param s the stream
1013 */
1014 private void writeObject(java.io.ObjectOutputStream s)
1015 throws java.io.IOException {
1016 lock.lock();
1017 try {
1018 // Write out capacity and any hidden stuff
1019 s.defaultWriteObject();
1020 // Write out all elements in the proper order.
1021 for (Node<E> p = first; p != null; p = p.next)
1022 s.writeObject(p.item);
1023 // Use trailing null as sentinel
1024 s.writeObject(null);
1025 } finally {
1026 lock.unlock();
1027 }
1028 }
1029
1030 /**
1031 * Reconstitute this deque from a stream (that is,
1032 * deserialize it).
1033 * @param s the stream
1034 */
1035 private void readObject(java.io.ObjectInputStream s)
1036 throws java.io.IOException, ClassNotFoundException {
1037 s.defaultReadObject();
1038 count = 0;
1039 first = null;
1040 last = null;
1041 // Read in all elements and place in queue
1042 for (;;) {
1043 E item = (E)s.readObject();
1044 if (item == null)
1045 break;
1046 add(item);
1047 }
1048 }
1049
1050}