ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/LinkedBlockingDeque.java
Revision: 1.82
Committed: Mon Oct 1 00:10:53 2018 UTC (5 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.81: +1 -1 lines
Log Message:
update to using jdk11 by default, except link to jdk10 javadocs;
sync @docRoot references in javadoc with upstream

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