ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.75
Committed: Tue Dec 27 23:49:46 2016 UTC (7 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.74: +1 -1 lines
Log Message:
remove redundant nulling

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, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package java.util.concurrent;
8
9 import java.util.AbstractQueue;
10 import java.util.Collection;
11 import java.util.Iterator;
12 import java.util.NoSuchElementException;
13 import java.util.Objects;
14 import java.util.Spliterator;
15 import java.util.Spliterators;
16 import java.util.concurrent.locks.Condition;
17 import java.util.concurrent.locks.ReentrantLock;
18 import java.util.function.Consumer;
19 import java.util.function.Predicate;
20
21 /**
22 * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
23 * linked nodes.
24 *
25 * <p>The optional capacity bound constructor argument serves as a
26 * way to prevent excessive expansion. The capacity, if unspecified,
27 * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
28 * dynamically created upon each insertion unless this would bring the
29 * deque above capacity.
30 *
31 * <p>Most operations run in constant time (ignoring time spent
32 * blocking). Exceptions include {@link #remove(Object) remove},
33 * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link
34 * #removeLastOccurrence removeLastOccurrence}, {@link #contains
35 * contains}, {@link #iterator iterator.remove()}, and the bulk
36 * operations, all of which run in linear time.
37 *
38 * <p>This class and its iterator implement all of the
39 * <em>optional</em> methods of the {@link Collection} and {@link
40 * Iterator} interfaces.
41 *
42 * <p>This class is a member of the
43 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
44 * Java Collections Framework</a>.
45 *
46 * @since 1.6
47 * @author Doug Lea
48 * @param <E> the type of elements held in this deque
49 */
50 public class LinkedBlockingDeque<E>
51 extends AbstractQueue<E>
52 implements BlockingDeque<E>, java.io.Serializable {
53
54 /*
55 * Implemented as a simple doubly-linked list protected by a
56 * single lock and using conditions to manage blocking.
57 *
58 * To implement weakly consistent iterators, it appears we need to
59 * keep all Nodes GC-reachable from a predecessor dequeued Node.
60 * That would cause two problems:
61 * - allow a rogue Iterator to cause unbounded memory retention
62 * - cause cross-generational linking of old Nodes to new Nodes if
63 * a Node was tenured while live, which generational GCs have a
64 * hard time dealing with, causing repeated major collections.
65 * However, only non-deleted Nodes need to be reachable from
66 * dequeued Nodes, and reachability does not necessarily have to
67 * be of the kind understood by the GC. We use the trick of
68 * linking a Node that has just been dequeued to itself. Such a
69 * self-link implicitly means to jump to "first" (for next links)
70 * or "last" (for prev links).
71 */
72
73 /*
74 * We have "diamond" multiple interface/abstract class inheritance
75 * here, and that introduces ambiguities. Often we want the
76 * BlockingDeque javadoc combined with the AbstractQueue
77 * implementation, so a lot of method specs are duplicated here.
78 */
79
80 private static final long serialVersionUID = -387911632671998426L;
81
82 /** Doubly-linked list node class */
83 static final class Node<E> {
84 /**
85 * The item, or null if this node has been removed.
86 */
87 E item;
88
89 /**
90 * One of:
91 * - the real predecessor Node
92 * - this Node, meaning the predecessor is tail
93 * - null, meaning there is no predecessor
94 */
95 Node<E> prev;
96
97 /**
98 * One of:
99 * - the real successor Node
100 * - this Node, meaning the successor is head
101 * - null, meaning there is no successor
102 */
103 Node<E> next;
104
105 Node(E x) {
106 item = x;
107 }
108 }
109
110 /**
111 * Pointer to first node.
112 * Invariant: (first == null && last == null) ||
113 * (first.prev == null && first.item != null)
114 */
115 transient Node<E> first;
116
117 /**
118 * Pointer to last node.
119 * Invariant: (first == null && last == null) ||
120 * (last.next == null && last.item != null)
121 */
122 transient Node<E> last;
123
124 /** Number of items in the deque */
125 private transient int count;
126
127 /** Maximum number of items in the deque */
128 private final int capacity;
129
130 /** Main lock guarding all access */
131 final ReentrantLock lock = new ReentrantLock();
132
133 /** Condition for waiting takes */
134 private final Condition notEmpty = lock.newCondition();
135
136 /** Condition for waiting puts */
137 private final Condition notFull = lock.newCondition();
138
139 /**
140 * Creates a {@code LinkedBlockingDeque} with a capacity of
141 * {@link Integer#MAX_VALUE}.
142 */
143 public LinkedBlockingDeque() {
144 this(Integer.MAX_VALUE);
145 }
146
147 /**
148 * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
149 *
150 * @param capacity the capacity of this deque
151 * @throws IllegalArgumentException if {@code capacity} is less than 1
152 */
153 public LinkedBlockingDeque(int capacity) {
154 if (capacity <= 0) throw new IllegalArgumentException();
155 this.capacity = capacity;
156 }
157
158 /**
159 * Creates a {@code LinkedBlockingDeque} with a capacity of
160 * {@link Integer#MAX_VALUE}, initially containing the elements of
161 * the given collection, added in traversal order of the
162 * collection's iterator.
163 *
164 * @param c the collection of elements to initially contain
165 * @throws NullPointerException if the specified collection or any
166 * of its elements are null
167 */
168 public LinkedBlockingDeque(Collection<? extends E> c) {
169 this(Integer.MAX_VALUE);
170 addAll(c);
171 }
172
173
174 // Basic linking and unlinking operations, called only while holding lock
175
176 /**
177 * Links node as first element, or returns false if full.
178 */
179 private boolean linkFirst(Node<E> node) {
180 // assert lock.isHeldByCurrentThread();
181 if (count >= capacity)
182 return false;
183 Node<E> f = first;
184 node.next = f;
185 first = node;
186 if (last == null)
187 last = node;
188 else
189 f.prev = node;
190 ++count;
191 notEmpty.signal();
192 return true;
193 }
194
195 /**
196 * Links node as last element, or returns false if full.
197 */
198 private boolean linkLast(Node<E> node) {
199 // assert lock.isHeldByCurrentThread();
200 if (count >= capacity)
201 return false;
202 Node<E> l = last;
203 node.prev = l;
204 last = node;
205 if (first == null)
206 first = node;
207 else
208 l.next = node;
209 ++count;
210 notEmpty.signal();
211 return true;
212 }
213
214 /**
215 * Removes and returns first element, or null if empty.
216 */
217 private E unlinkFirst() {
218 // assert lock.isHeldByCurrentThread();
219 Node<E> f = first;
220 if (f == null)
221 return null;
222 Node<E> n = f.next;
223 E item = f.item;
224 f.item = null;
225 f.next = f; // help GC
226 first = n;
227 if (n == null)
228 last = null;
229 else
230 n.prev = null;
231 --count;
232 notFull.signal();
233 return item;
234 }
235
236 /**
237 * Removes and returns last element, or null if empty.
238 */
239 private E unlinkLast() {
240 // assert lock.isHeldByCurrentThread();
241 Node<E> l = last;
242 if (l == null)
243 return null;
244 Node<E> p = l.prev;
245 E item = l.item;
246 l.item = null;
247 l.prev = l; // help GC
248 last = p;
249 if (p == null)
250 first = null;
251 else
252 p.next = null;
253 --count;
254 notFull.signal();
255 return item;
256 }
257
258 /**
259 * Unlinks x.
260 */
261 void unlink(Node<E> x) {
262 // assert lock.isHeldByCurrentThread();
263 // assert x.item != null;
264 Node<E> p = x.prev;
265 Node<E> n = x.next;
266 if (p == null) {
267 unlinkFirst();
268 } else if (n == null) {
269 unlinkLast();
270 } else {
271 p.next = n;
272 n.prev = p;
273 x.item = null;
274 // Don't mess with x's links. They may still be in use by
275 // an iterator.
276 --count;
277 notFull.signal();
278 }
279 }
280
281 // BlockingDeque methods
282
283 /**
284 * @throws IllegalStateException if this deque is full
285 * @throws NullPointerException {@inheritDoc}
286 */
287 public void addFirst(E e) {
288 if (!offerFirst(e))
289 throw new IllegalStateException("Deque full");
290 }
291
292 /**
293 * @throws IllegalStateException if this deque is full
294 * @throws NullPointerException {@inheritDoc}
295 */
296 public void addLast(E e) {
297 if (!offerLast(e))
298 throw new IllegalStateException("Deque full");
299 }
300
301 /**
302 * @throws NullPointerException {@inheritDoc}
303 */
304 public boolean offerFirst(E e) {
305 if (e == null) throw new NullPointerException();
306 Node<E> node = new Node<E>(e);
307 final ReentrantLock lock = this.lock;
308 lock.lock();
309 try {
310 return linkFirst(node);
311 } finally {
312 // checkInvariants();
313 lock.unlock();
314 }
315 }
316
317 /**
318 * @throws NullPointerException {@inheritDoc}
319 */
320 public boolean offerLast(E e) {
321 if (e == null) throw new NullPointerException();
322 Node<E> node = new Node<E>(e);
323 final ReentrantLock lock = this.lock;
324 lock.lock();
325 try {
326 return linkLast(node);
327 } finally {
328 // checkInvariants();
329 lock.unlock();
330 }
331 }
332
333 /**
334 * @throws NullPointerException {@inheritDoc}
335 * @throws InterruptedException {@inheritDoc}
336 */
337 public void putFirst(E e) throws InterruptedException {
338 if (e == null) throw new NullPointerException();
339 Node<E> node = new Node<E>(e);
340 final ReentrantLock lock = this.lock;
341 lock.lock();
342 try {
343 while (!linkFirst(node))
344 notFull.await();
345 } finally {
346 // checkInvariants();
347 lock.unlock();
348 }
349 }
350
351 /**
352 * @throws NullPointerException {@inheritDoc}
353 * @throws InterruptedException {@inheritDoc}
354 */
355 public void putLast(E e) throws InterruptedException {
356 if (e == null) throw new NullPointerException();
357 Node<E> node = new Node<E>(e);
358 final ReentrantLock lock = this.lock;
359 lock.lock();
360 try {
361 while (!linkLast(node))
362 notFull.await();
363 } finally {
364 // checkInvariants();
365 lock.unlock();
366 }
367 }
368
369 /**
370 * @throws NullPointerException {@inheritDoc}
371 * @throws InterruptedException {@inheritDoc}
372 */
373 public boolean offerFirst(E e, long timeout, TimeUnit unit)
374 throws InterruptedException {
375 if (e == null) throw new NullPointerException();
376 Node<E> node = new Node<E>(e);
377 long nanos = unit.toNanos(timeout);
378 final ReentrantLock lock = this.lock;
379 lock.lockInterruptibly();
380 try {
381 while (!linkFirst(node)) {
382 if (nanos <= 0L)
383 return false;
384 nanos = notFull.awaitNanos(nanos);
385 }
386 return true;
387 } finally {
388 // checkInvariants();
389 lock.unlock();
390 }
391 }
392
393 /**
394 * @throws NullPointerException {@inheritDoc}
395 * @throws InterruptedException {@inheritDoc}
396 */
397 public boolean offerLast(E e, long timeout, TimeUnit unit)
398 throws InterruptedException {
399 if (e == null) throw new NullPointerException();
400 Node<E> node = new Node<E>(e);
401 long nanos = unit.toNanos(timeout);
402 final ReentrantLock lock = this.lock;
403 lock.lockInterruptibly();
404 try {
405 while (!linkLast(node)) {
406 if (nanos <= 0L)
407 return false;
408 nanos = notFull.awaitNanos(nanos);
409 }
410 return true;
411 } finally {
412 // checkInvariants();
413 lock.unlock();
414 }
415 }
416
417 /**
418 * @throws NoSuchElementException {@inheritDoc}
419 */
420 public E removeFirst() {
421 E x = pollFirst();
422 if (x == null) throw new NoSuchElementException();
423 return x;
424 }
425
426 /**
427 * @throws NoSuchElementException {@inheritDoc}
428 */
429 public E removeLast() {
430 E x = pollLast();
431 if (x == null) throw new NoSuchElementException();
432 return x;
433 }
434
435 public E pollFirst() {
436 final ReentrantLock lock = this.lock;
437 lock.lock();
438 try {
439 return unlinkFirst();
440 } finally {
441 // checkInvariants();
442 lock.unlock();
443 }
444 }
445
446 public E pollLast() {
447 final ReentrantLock lock = this.lock;
448 lock.lock();
449 try {
450 return unlinkLast();
451 } finally {
452 // checkInvariants();
453 lock.unlock();
454 }
455 }
456
457 public E takeFirst() throws InterruptedException {
458 final ReentrantLock lock = this.lock;
459 lock.lock();
460 try {
461 E x;
462 while ( (x = unlinkFirst()) == null)
463 notEmpty.await();
464 return x;
465 } finally {
466 // checkInvariants();
467 lock.unlock();
468 }
469 }
470
471 public E takeLast() throws InterruptedException {
472 final ReentrantLock lock = this.lock;
473 lock.lock();
474 try {
475 E x;
476 while ( (x = unlinkLast()) == null)
477 notEmpty.await();
478 return x;
479 } finally {
480 // checkInvariants();
481 lock.unlock();
482 }
483 }
484
485 public E pollFirst(long timeout, TimeUnit unit)
486 throws InterruptedException {
487 long nanos = unit.toNanos(timeout);
488 final ReentrantLock lock = this.lock;
489 lock.lockInterruptibly();
490 try {
491 E x;
492 while ( (x = unlinkFirst()) == null) {
493 if (nanos <= 0L)
494 return null;
495 nanos = notEmpty.awaitNanos(nanos);
496 }
497 return x;
498 } finally {
499 // checkInvariants();
500 lock.unlock();
501 }
502 }
503
504 public E pollLast(long timeout, TimeUnit unit)
505 throws InterruptedException {
506 long nanos = unit.toNanos(timeout);
507 final ReentrantLock lock = this.lock;
508 lock.lockInterruptibly();
509 try {
510 E x;
511 while ( (x = unlinkLast()) == null) {
512 if (nanos <= 0L)
513 return null;
514 nanos = notEmpty.awaitNanos(nanos);
515 }
516 return x;
517 } finally {
518 // checkInvariants();
519 lock.unlock();
520 }
521 }
522
523 /**
524 * @throws NoSuchElementException {@inheritDoc}
525 */
526 public E getFirst() {
527 E x = peekFirst();
528 if (x == null) throw new NoSuchElementException();
529 return x;
530 }
531
532 /**
533 * @throws NoSuchElementException {@inheritDoc}
534 */
535 public E getLast() {
536 E x = peekLast();
537 if (x == null) throw new NoSuchElementException();
538 return x;
539 }
540
541 public E peekFirst() {
542 final ReentrantLock lock = this.lock;
543 lock.lock();
544 try {
545 return (first == null) ? null : first.item;
546 } finally {
547 // checkInvariants();
548 lock.unlock();
549 }
550 }
551
552 public E peekLast() {
553 final ReentrantLock lock = this.lock;
554 lock.lock();
555 try {
556 return (last == null) ? null : last.item;
557 } finally {
558 // checkInvariants();
559 lock.unlock();
560 }
561 }
562
563 public boolean removeFirstOccurrence(Object o) {
564 if (o == null) return false;
565 final ReentrantLock lock = this.lock;
566 lock.lock();
567 try {
568 for (Node<E> p = first; p != null; p = p.next) {
569 if (o.equals(p.item)) {
570 unlink(p);
571 return true;
572 }
573 }
574 return false;
575 } finally {
576 // checkInvariants();
577 lock.unlock();
578 }
579 }
580
581 public boolean removeLastOccurrence(Object o) {
582 if (o == null) return false;
583 final ReentrantLock lock = this.lock;
584 lock.lock();
585 try {
586 for (Node<E> p = last; p != null; p = p.prev) {
587 if (o.equals(p.item)) {
588 unlink(p);
589 return true;
590 }
591 }
592 return false;
593 } finally {
594 // checkInvariants();
595 lock.unlock();
596 }
597 }
598
599 // BlockingQueue methods
600
601 /**
602 * Inserts the specified element at the end of this deque unless it would
603 * violate capacity restrictions. When using a capacity-restricted deque,
604 * it is generally preferable to use method {@link #offer(Object) offer}.
605 *
606 * <p>This method is equivalent to {@link #addLast}.
607 *
608 * @throws IllegalStateException if this deque is full
609 * @throws NullPointerException if the specified element is null
610 */
611 public boolean add(E e) {
612 addLast(e);
613 return true;
614 }
615
616 /**
617 * @throws NullPointerException if the specified element is null
618 */
619 public boolean offer(E e) {
620 return offerLast(e);
621 }
622
623 /**
624 * @throws NullPointerException {@inheritDoc}
625 * @throws InterruptedException {@inheritDoc}
626 */
627 public void put(E e) throws InterruptedException {
628 putLast(e);
629 }
630
631 /**
632 * @throws NullPointerException {@inheritDoc}
633 * @throws InterruptedException {@inheritDoc}
634 */
635 public boolean offer(E e, long timeout, TimeUnit unit)
636 throws InterruptedException {
637 return offerLast(e, timeout, unit);
638 }
639
640 /**
641 * Retrieves and removes the head of the queue represented by this deque.
642 * This method differs from {@link #poll poll} only in that it throws an
643 * exception if this deque is empty.
644 *
645 * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
646 *
647 * @return the head of the queue represented by this deque
648 * @throws NoSuchElementException if this deque is empty
649 */
650 public E remove() {
651 return removeFirst();
652 }
653
654 public E poll() {
655 return pollFirst();
656 }
657
658 public E take() throws InterruptedException {
659 return takeFirst();
660 }
661
662 public E poll(long timeout, TimeUnit unit) throws InterruptedException {
663 return pollFirst(timeout, unit);
664 }
665
666 /**
667 * Retrieves, but does not remove, the head of the queue represented by
668 * this deque. This method differs from {@link #peek peek} only in that
669 * it throws an exception if this deque is empty.
670 *
671 * <p>This method is equivalent to {@link #getFirst() getFirst}.
672 *
673 * @return the head of the queue represented by this deque
674 * @throws NoSuchElementException if this deque is empty
675 */
676 public E element() {
677 return getFirst();
678 }
679
680 public E peek() {
681 return peekFirst();
682 }
683
684 /**
685 * Returns the number of additional elements that this deque can ideally
686 * (in the absence of memory or resource constraints) accept without
687 * blocking. This is always equal to the initial capacity of this deque
688 * less the current {@code size} of this deque.
689 *
690 * <p>Note that you <em>cannot</em> always tell if an attempt to insert
691 * an element will succeed by inspecting {@code remainingCapacity}
692 * because it may be the case that another thread is about to
693 * insert or remove an element.
694 */
695 public int remainingCapacity() {
696 final ReentrantLock lock = this.lock;
697 lock.lock();
698 try {
699 return capacity - count;
700 } finally {
701 // checkInvariants();
702 lock.unlock();
703 }
704 }
705
706 /**
707 * @throws UnsupportedOperationException {@inheritDoc}
708 * @throws ClassCastException {@inheritDoc}
709 * @throws NullPointerException {@inheritDoc}
710 * @throws IllegalArgumentException {@inheritDoc}
711 */
712 public int drainTo(Collection<? super E> c) {
713 return drainTo(c, Integer.MAX_VALUE);
714 }
715
716 /**
717 * @throws UnsupportedOperationException {@inheritDoc}
718 * @throws ClassCastException {@inheritDoc}
719 * @throws NullPointerException {@inheritDoc}
720 * @throws IllegalArgumentException {@inheritDoc}
721 */
722 public int drainTo(Collection<? super E> c, int maxElements) {
723 Objects.requireNonNull(c);
724 if (c == this)
725 throw new IllegalArgumentException();
726 if (maxElements <= 0)
727 return 0;
728 final ReentrantLock lock = this.lock;
729 lock.lock();
730 try {
731 int n = Math.min(maxElements, count);
732 for (int i = 0; i < n; i++) {
733 c.add(first.item); // In this order, in case add() throws.
734 unlinkFirst();
735 }
736 return n;
737 } finally {
738 // checkInvariants();
739 lock.unlock();
740 }
741 }
742
743 // Stack methods
744
745 /**
746 * @throws IllegalStateException if this deque is full
747 * @throws NullPointerException {@inheritDoc}
748 */
749 public void push(E e) {
750 addFirst(e);
751 }
752
753 /**
754 * @throws NoSuchElementException {@inheritDoc}
755 */
756 public E pop() {
757 return removeFirst();
758 }
759
760 // Collection methods
761
762 /**
763 * Removes the first occurrence of the specified element from this deque.
764 * If the deque does not contain the element, it is unchanged.
765 * More formally, removes the first element {@code e} such that
766 * {@code o.equals(e)} (if such an element exists).
767 * Returns {@code true} if this deque contained the specified element
768 * (or equivalently, if this deque changed as a result of the call).
769 *
770 * <p>This method is equivalent to
771 * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
772 *
773 * @param o element to be removed from this deque, if present
774 * @return {@code true} if this deque changed as a result of the call
775 */
776 public boolean remove(Object o) {
777 return removeFirstOccurrence(o);
778 }
779
780 /**
781 * Returns the number of elements in this deque.
782 *
783 * @return the number of elements in this deque
784 */
785 public int size() {
786 final ReentrantLock lock = this.lock;
787 lock.lock();
788 try {
789 return count;
790 } finally {
791 // checkInvariants();
792 lock.unlock();
793 }
794 }
795
796 /**
797 * Returns {@code true} if this deque contains the specified element.
798 * More formally, returns {@code true} if and only if this deque contains
799 * at least one element {@code e} such that {@code o.equals(e)}.
800 *
801 * @param o object to be checked for containment in this deque
802 * @return {@code true} if this deque contains the specified element
803 */
804 public boolean contains(Object o) {
805 if (o == null) return false;
806 final ReentrantLock lock = this.lock;
807 lock.lock();
808 try {
809 for (Node<E> p = first; p != null; p = p.next)
810 if (o.equals(p.item))
811 return true;
812 return false;
813 } finally {
814 // checkInvariants();
815 lock.unlock();
816 }
817 }
818
819 /**
820 * Appends all of the elements in the specified collection to the end of
821 * this deque, in the order that they are returned by the specified
822 * collection's iterator. Attempts to {@code addAll} of a deque to
823 * itself result in {@code IllegalArgumentException}.
824 *
825 * @param c the elements to be inserted into this deque
826 * @return {@code true} if this deque changed as a result of the call
827 * @throws NullPointerException if the specified collection or any
828 * of its elements are null
829 * @throws IllegalArgumentException if the collection is this deque
830 * @throws IllegalStateException if this deque is full
831 * @see #add(Object)
832 */
833 public boolean addAll(Collection<? extends E> c) {
834 if (c == this)
835 // As historically specified in AbstractQueue#addAll
836 throw new IllegalArgumentException();
837
838 // Copy c into a private chain of Nodes
839 Node<E> beg = null, end = null;
840 int n = 0;
841 for (E e : c) {
842 Objects.requireNonNull(e);
843 n++;
844 Node<E> newNode = new Node<E>(e);
845 if (beg == null)
846 beg = end = newNode;
847 else {
848 end.next = newNode;
849 newNode.prev = end;
850 end = newNode;
851 }
852 }
853 if (beg == null)
854 return false;
855
856 // Atomically append the chain at the end
857 final ReentrantLock lock = this.lock;
858 lock.lock();
859 try {
860 if (count + n <= capacity) {
861 beg.prev = last;
862 if (first == null)
863 first = beg;
864 else
865 last.next = beg;
866 last = end;
867 count += n;
868 notEmpty.signalAll();
869 return true;
870 }
871 } finally {
872 // checkInvariants();
873 lock.unlock();
874 }
875 // Fall back to historic non-atomic implementation, failing
876 // with IllegalStateException when the capacity is exceeded.
877 return super.addAll(c);
878 }
879
880 /**
881 * Returns an array containing all of the elements in this deque, in
882 * proper sequence (from first to last element).
883 *
884 * <p>The returned array will be "safe" in that no references to it are
885 * maintained by this deque. (In other words, this method must allocate
886 * a new array). The caller is thus free to modify the returned array.
887 *
888 * <p>This method acts as bridge between array-based and collection-based
889 * APIs.
890 *
891 * @return an array containing all of the elements in this deque
892 */
893 @SuppressWarnings("unchecked")
894 public Object[] toArray() {
895 final ReentrantLock lock = this.lock;
896 lock.lock();
897 try {
898 Object[] a = new Object[count];
899 int k = 0;
900 for (Node<E> p = first; p != null; p = p.next)
901 a[k++] = p.item;
902 return a;
903 } finally {
904 // checkInvariants();
905 lock.unlock();
906 }
907 }
908
909 /**
910 * Returns an array containing all of the elements in this deque, in
911 * proper sequence; the runtime type of the returned array is that of
912 * the specified array. If the deque fits in the specified array, it
913 * is returned therein. Otherwise, a new array is allocated with the
914 * runtime type of the specified array and the size of this deque.
915 *
916 * <p>If this deque fits in the specified array with room to spare
917 * (i.e., the array has more elements than this deque), the element in
918 * the array immediately following the end of the deque is set to
919 * {@code null}.
920 *
921 * <p>Like the {@link #toArray()} method, this method acts as bridge between
922 * array-based and collection-based APIs. Further, this method allows
923 * precise control over the runtime type of the output array, and may,
924 * under certain circumstances, be used to save allocation costs.
925 *
926 * <p>Suppose {@code x} is a deque known to contain only strings.
927 * The following code can be used to dump the deque into a newly
928 * allocated array of {@code String}:
929 *
930 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
931 *
932 * Note that {@code toArray(new Object[0])} is identical in function to
933 * {@code toArray()}.
934 *
935 * @param a the array into which the elements of the deque are to
936 * be stored, if it is big enough; otherwise, a new array of the
937 * same runtime type is allocated for this purpose
938 * @return an array containing all of the elements in this deque
939 * @throws ArrayStoreException if the runtime type of the specified array
940 * is not a supertype of the runtime type of every element in
941 * this deque
942 * @throws NullPointerException if the specified array is null
943 */
944 @SuppressWarnings("unchecked")
945 public <T> T[] toArray(T[] a) {
946 final ReentrantLock lock = this.lock;
947 lock.lock();
948 try {
949 if (a.length < count)
950 a = (T[])java.lang.reflect.Array.newInstance
951 (a.getClass().getComponentType(), count);
952
953 int k = 0;
954 for (Node<E> p = first; p != null; p = p.next)
955 a[k++] = (T)p.item;
956 if (a.length > k)
957 a[k] = null;
958 return a;
959 } finally {
960 // checkInvariants();
961 lock.unlock();
962 }
963 }
964
965 public String toString() {
966 return Helpers.collectionToString(this);
967 }
968
969 /**
970 * Atomically removes all of the elements from this deque.
971 * The deque will be empty after this call returns.
972 */
973 public void clear() {
974 final ReentrantLock lock = this.lock;
975 lock.lock();
976 try {
977 for (Node<E> f = first; f != null; ) {
978 f.item = null;
979 Node<E> n = f.next;
980 f.prev = null;
981 f.next = null;
982 f = n;
983 }
984 first = last = null;
985 count = 0;
986 notFull.signalAll();
987 } finally {
988 // checkInvariants();
989 lock.unlock();
990 }
991 }
992
993 /**
994 * Used for any element traversal that is not entirely under lock.
995 * Such traversals must handle both:
996 * - dequeued nodes (p.next == p)
997 * - (possibly multiple) interior removed nodes (p.item == null)
998 */
999 Node<E> succ(Node<E> p) {
1000 return (p == (p = p.next)) ? first : p;
1001 }
1002
1003 /**
1004 * Returns an iterator over the elements in this deque in proper sequence.
1005 * The elements will be returned in order from first (head) to last (tail).
1006 *
1007 * <p>The returned iterator is
1008 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1009 *
1010 * @return an iterator over the elements in this deque in proper sequence
1011 */
1012 public Iterator<E> iterator() {
1013 return new Itr();
1014 }
1015
1016 /**
1017 * Returns an iterator over the elements in this deque in reverse
1018 * sequential order. The elements will be returned in order from
1019 * last (tail) to first (head).
1020 *
1021 * <p>The returned iterator is
1022 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1023 *
1024 * @return an iterator over the elements in this deque in reverse order
1025 */
1026 public Iterator<E> descendingIterator() {
1027 return new DescendingItr();
1028 }
1029
1030 /**
1031 * Base class for LinkedBlockingDeque iterators.
1032 */
1033 private abstract class AbstractItr implements Iterator<E> {
1034 /**
1035 * The next node to return in next().
1036 */
1037 Node<E> next;
1038
1039 /**
1040 * nextItem holds on to item fields because once we claim that
1041 * an element exists in hasNext(), we must return item read
1042 * under lock even if it was in the process of being removed
1043 * when hasNext() was called.
1044 */
1045 E nextItem;
1046
1047 /**
1048 * Node returned by most recent call to next. Needed by remove.
1049 * Reset to null if this element is deleted by a call to remove.
1050 */
1051 private Node<E> lastRet;
1052
1053 abstract Node<E> firstNode();
1054 abstract Node<E> nextNode(Node<E> n);
1055
1056 private Node<E> succ(Node<E> p) {
1057 return (p == (p = nextNode(p))) ? firstNode() : p;
1058 }
1059
1060 AbstractItr() {
1061 // set to initial position
1062 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1063 lock.lock();
1064 try {
1065 if ((next = firstNode()) != null)
1066 nextItem = next.item;
1067 } finally {
1068 // checkInvariants();
1069 lock.unlock();
1070 }
1071 }
1072
1073 public boolean hasNext() {
1074 return next != null;
1075 }
1076
1077 public E next() {
1078 Node<E> p;
1079 if ((p = next) == null)
1080 throw new NoSuchElementException();
1081 lastRet = p;
1082 E x = nextItem;
1083 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1084 lock.lock();
1085 try {
1086 E e = null;
1087 for (p = nextNode(p); p != null && (e = p.item) == null; )
1088 p = succ(p);
1089 next = p;
1090 nextItem = e;
1091 } finally {
1092 // checkInvariants();
1093 lock.unlock();
1094 }
1095 return x;
1096 }
1097
1098 public void forEachRemaining(Consumer<? super E> action) {
1099 // A variant of forEachFrom
1100 Objects.requireNonNull(action);
1101 Node<E> p;
1102 if ((p = next) == null) return;
1103 lastRet = p;
1104 next = null;
1105 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1106 final int batchSize = 32;
1107 Object[] es = null;
1108 int n, len = 1;
1109 do {
1110 lock.lock();
1111 try {
1112 if (es == null) {
1113 p = nextNode(p);
1114 for (Node<E> q = p; q != null; q = succ(q))
1115 if (q.item != null && ++len == batchSize)
1116 break;
1117 es = new Object[len];
1118 es[0] = nextItem;
1119 nextItem = null;
1120 n = 1;
1121 } else
1122 n = 0;
1123 for (; p != null && n < len; p = succ(p))
1124 if ((es[n] = p.item) != null) {
1125 lastRet = p;
1126 n++;
1127 }
1128 } finally {
1129 // checkInvariants();
1130 lock.unlock();
1131 }
1132 for (int i = 0; i < n; i++) {
1133 @SuppressWarnings("unchecked") E e = (E) es[i];
1134 action.accept(e);
1135 }
1136 } while (n > 0 && p != null);
1137 }
1138
1139 public void remove() {
1140 Node<E> n = lastRet;
1141 if (n == null)
1142 throw new IllegalStateException();
1143 lastRet = null;
1144 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1145 lock.lock();
1146 try {
1147 if (n.item != null)
1148 unlink(n);
1149 } finally {
1150 // checkInvariants();
1151 lock.unlock();
1152 }
1153 }
1154 }
1155
1156 /** Forward iterator */
1157 private class Itr extends AbstractItr {
1158 Itr() {} // prevent access constructor creation
1159 Node<E> firstNode() { return first; }
1160 Node<E> nextNode(Node<E> n) { return n.next; }
1161 }
1162
1163 /** Descending iterator */
1164 private class DescendingItr extends AbstractItr {
1165 DescendingItr() {} // prevent access constructor creation
1166 Node<E> firstNode() { return last; }
1167 Node<E> nextNode(Node<E> n) { return n.prev; }
1168 }
1169
1170 /**
1171 * A customized variant of Spliterators.IteratorSpliterator.
1172 * Keep this class in sync with (very similar) LBQSpliterator.
1173 */
1174 private final class LBDSpliterator implements Spliterator<E> {
1175 static final int MAX_BATCH = 1 << 25; // max batch array size;
1176 Node<E> current; // current node; null until initialized
1177 int batch; // batch size for splits
1178 boolean exhausted; // true when no more nodes
1179 long est = size(); // size estimate
1180
1181 LBDSpliterator() {}
1182
1183 public long estimateSize() { return est; }
1184
1185 public Spliterator<E> trySplit() {
1186 Node<E> h;
1187 if (!exhausted &&
1188 ((h = current) != null || (h = first) != null)
1189 && h.next != null) {
1190 int n = batch = Math.min(batch + 1, MAX_BATCH);
1191 Object[] a = new Object[n];
1192 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1193 int i = 0;
1194 Node<E> p = current;
1195 lock.lock();
1196 try {
1197 if (p != null || (p = first) != null)
1198 for (; p != null && i < n; p = succ(p))
1199 if ((a[i] = p.item) != null)
1200 i++;
1201 } finally {
1202 // checkInvariants();
1203 lock.unlock();
1204 }
1205 if ((current = p) == null) {
1206 est = 0L;
1207 exhausted = true;
1208 }
1209 else if ((est -= i) < 0L)
1210 est = 0L;
1211 if (i > 0)
1212 return Spliterators.spliterator
1213 (a, 0, i, (Spliterator.ORDERED |
1214 Spliterator.NONNULL |
1215 Spliterator.CONCURRENT));
1216 }
1217 return null;
1218 }
1219
1220 public boolean tryAdvance(Consumer<? super E> action) {
1221 Objects.requireNonNull(action);
1222 if (!exhausted) {
1223 E e = null;
1224 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
1225 lock.lock();
1226 try {
1227 Node<E> p;
1228 if ((p = current) != null || (p = first) != null)
1229 do {
1230 e = p.item;
1231 p = succ(p);
1232 } while (e == null && p != null);
1233 if ((current = p) == null)
1234 exhausted = true;
1235 } finally {
1236 // checkInvariants();
1237 lock.unlock();
1238 }
1239 if (e != null) {
1240 action.accept(e);
1241 return true;
1242 }
1243 }
1244 return false;
1245 }
1246
1247 public void forEachRemaining(Consumer<? super E> action) {
1248 Objects.requireNonNull(action);
1249 if (!exhausted) {
1250 exhausted = true;
1251 Node<E> p = current;
1252 current = null;
1253 forEachFrom(action, p);
1254 }
1255 }
1256
1257 public int characteristics() {
1258 return (Spliterator.ORDERED |
1259 Spliterator.NONNULL |
1260 Spliterator.CONCURRENT);
1261 }
1262 }
1263
1264 /**
1265 * Returns a {@link Spliterator} over the elements in this deque.
1266 *
1267 * <p>The returned spliterator is
1268 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1269 *
1270 * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
1271 * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
1272 *
1273 * @implNote
1274 * The {@code Spliterator} implements {@code trySplit} to permit limited
1275 * parallelism.
1276 *
1277 * @return a {@code Spliterator} over the elements in this deque
1278 * @since 1.8
1279 */
1280 public Spliterator<E> spliterator() {
1281 return new LBDSpliterator();
1282 }
1283
1284 /**
1285 * @throws NullPointerException {@inheritDoc}
1286 */
1287 public void forEach(Consumer<? super E> action) {
1288 Objects.requireNonNull(action);
1289 forEachFrom(action, null);
1290 }
1291
1292 /**
1293 * Runs action on each element found during a traversal starting at p.
1294 * If p is null, traversal starts at head.
1295 */
1296 void forEachFrom(Consumer<? super E> action, Node<E> p) {
1297 // Extract batches of elements while holding the lock; then
1298 // run the action on the elements while not
1299 final ReentrantLock lock = this.lock;
1300 final int batchSize = 32; // max number of elements per batch
1301 Object[] es = null; // container for batch of elements
1302 int n, len = 0;
1303 do {
1304 lock.lock();
1305 try {
1306 if (es == null) {
1307 if (p == null) p = first;
1308 for (Node<E> q = p; q != null; q = succ(q))
1309 if (q.item != null && ++len == batchSize)
1310 break;
1311 es = new Object[len];
1312 }
1313 for (n = 0; p != null && n < len; p = succ(p))
1314 if ((es[n] = p.item) != null)
1315 n++;
1316 } finally {
1317 // checkInvariants();
1318 lock.unlock();
1319 }
1320 for (int i = 0; i < n; i++) {
1321 @SuppressWarnings("unchecked") E e = (E) es[i];
1322 action.accept(e);
1323 }
1324 } while (n > 0 && p != null);
1325 }
1326
1327 /**
1328 * @throws NullPointerException {@inheritDoc}
1329 */
1330 public boolean removeIf(Predicate<? super E> filter) {
1331 Objects.requireNonNull(filter);
1332 return bulkRemove(filter);
1333 }
1334
1335 /**
1336 * @throws NullPointerException {@inheritDoc}
1337 */
1338 public boolean removeAll(Collection<?> c) {
1339 Objects.requireNonNull(c);
1340 return bulkRemove(e -> c.contains(e));
1341 }
1342
1343 /**
1344 * @throws NullPointerException {@inheritDoc}
1345 */
1346 public boolean retainAll(Collection<?> c) {
1347 Objects.requireNonNull(c);
1348 return bulkRemove(e -> !c.contains(e));
1349 }
1350
1351 /** Implementation of bulk remove methods. */
1352 @SuppressWarnings("unchecked")
1353 private boolean bulkRemove(Predicate<? super E> filter) {
1354 boolean removed = false;
1355 Node<E> p = null;
1356 final ReentrantLock lock = this.lock;
1357 Node<E>[] nodes = null;
1358 int n, len = 0;
1359 do {
1360 // 1. Extract batch of up to 64 elements while holding the lock.
1361 long deathRow = 0; // "bitset" of size 64
1362 lock.lock();
1363 try {
1364 if (nodes == null) {
1365 if (p == null) p = first;
1366 for (Node<E> q = p; q != null; q = succ(q))
1367 if (q.item != null && ++len == 64)
1368 break;
1369 nodes = (Node<E>[]) new Node<?>[len];
1370 }
1371 for (n = 0; p != null && n < len; p = succ(p))
1372 nodes[n++] = p;
1373 } finally {
1374 // checkInvariants();
1375 lock.unlock();
1376 }
1377
1378 // 2. Run the filter on the elements while lock is free.
1379 for (int i = 0; i < n; i++) {
1380 final E e;
1381 if ((e = nodes[i].item) != null && filter.test(e))
1382 deathRow |= 1L << i;
1383 }
1384
1385 // 3. Remove any filtered elements while holding the lock.
1386 if (deathRow != 0) {
1387 lock.lock();
1388 try {
1389 for (int i = 0; i < n; i++) {
1390 final Node<E> q;
1391 if ((deathRow & (1L << i)) != 0L
1392 && (q = nodes[i]).item != null) {
1393 unlink(q);
1394 removed = true;
1395 }
1396 }
1397 } finally {
1398 // checkInvariants();
1399 lock.unlock();
1400 }
1401 }
1402 } while (n > 0 && p != null);
1403 return removed;
1404 }
1405
1406 /**
1407 * Saves this deque to a stream (that is, serializes it).
1408 *
1409 * @param s the stream
1410 * @throws java.io.IOException if an I/O error occurs
1411 * @serialData The capacity (int), followed by elements (each an
1412 * {@code Object}) in the proper order, followed by a null
1413 */
1414 private void writeObject(java.io.ObjectOutputStream s)
1415 throws java.io.IOException {
1416 final ReentrantLock lock = this.lock;
1417 lock.lock();
1418 try {
1419 // Write out capacity and any hidden stuff
1420 s.defaultWriteObject();
1421 // Write out all elements in the proper order.
1422 for (Node<E> p = first; p != null; p = p.next)
1423 s.writeObject(p.item);
1424 // Use trailing null as sentinel
1425 s.writeObject(null);
1426 } finally {
1427 // checkInvariants();
1428 lock.unlock();
1429 }
1430 }
1431
1432 /**
1433 * Reconstitutes this deque from a stream (that is, deserializes it).
1434 * @param s the stream
1435 * @throws ClassNotFoundException if the class of a serialized object
1436 * could not be found
1437 * @throws java.io.IOException if an I/O error occurs
1438 */
1439 private void readObject(java.io.ObjectInputStream s)
1440 throws java.io.IOException, ClassNotFoundException {
1441 s.defaultReadObject();
1442 count = 0;
1443 first = null;
1444 last = null;
1445 // Read in all elements and place in queue
1446 for (;;) {
1447 @SuppressWarnings("unchecked") E item = (E)s.readObject();
1448 if (item == null)
1449 break;
1450 add(item);
1451 }
1452 }
1453
1454 void checkInvariants() {
1455 // assert lock.isHeldByCurrentThread();
1456 // Nodes may get self-linked or lose their item, but only
1457 // after being unlinked and becoming unreachable from first.
1458 for (Node<E> p = first; p != null; p = p.next) {
1459 // assert p.next != p;
1460 // assert p.item != null;
1461 }
1462 }
1463
1464 }