ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentLinkedDeque.java
Revision: 1.72
Committed: Mon Jun 13 15:31:25 2016 UTC (7 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.71: +1 -1 lines
Log Message:
fix JDK-8159351: non-atomic "bulk" ops note in class javadoc for ConcurrentLinkedQueue, ConcurrentLinkedDeque, & LinkedTransferQueue should not include equals

File Contents

# Content
1 /*
2 * Written by Doug Lea and Martin Buchholz with assistance from members of
3 * JCP JSR-166 Expert Group and released to the public domain, as explained
4 * at http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package java.util.concurrent;
8
9 import java.lang.invoke.MethodHandles;
10 import java.lang.invoke.VarHandle;
11 import java.util.AbstractCollection;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.Deque;
15 import java.util.Iterator;
16 import java.util.NoSuchElementException;
17 import java.util.Objects;
18 import java.util.Queue;
19 import java.util.Spliterator;
20 import java.util.Spliterators;
21 import java.util.function.Consumer;
22
23 /**
24 * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
25 * Concurrent insertion, removal, and access operations execute safely
26 * across multiple threads.
27 * A {@code ConcurrentLinkedDeque} is an appropriate choice when
28 * many threads will share access to a common collection.
29 * Like most other concurrent collection implementations, this class
30 * does not permit the use of {@code null} elements.
31 *
32 * <p>Iterators and spliterators are
33 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
34 *
35 * <p>Beware that, unlike in most collections, the {@code size} method
36 * is <em>NOT</em> a constant-time operation. Because of the
37 * asynchronous nature of these deques, determining the current number
38 * of elements requires a traversal of the elements, and so may report
39 * inaccurate results if this collection is modified during traversal.
40 * Additionally, the bulk operations {@code addAll},
41 * {@code removeAll}, {@code retainAll}, {@code containsAll},
42 * and {@code toArray} are <em>not</em> guaranteed
43 * to be performed atomically. For example, an iterator operating
44 * concurrently with an {@code addAll} operation might view only some
45 * of the added elements.
46 *
47 * <p>This class and its iterator implement all of the <em>optional</em>
48 * methods of the {@link Deque} and {@link Iterator} interfaces.
49 *
50 * <p>Memory consistency effects: As with other concurrent collections,
51 * actions in a thread prior to placing an object into a
52 * {@code ConcurrentLinkedDeque}
53 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
54 * actions subsequent to the access or removal of that element from
55 * the {@code ConcurrentLinkedDeque} in another thread.
56 *
57 * <p>This class is a member of the
58 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
59 * Java Collections Framework</a>.
60 *
61 * @since 1.7
62 * @author Doug Lea
63 * @author Martin Buchholz
64 * @param <E> the type of elements held in this deque
65 */
66 public class ConcurrentLinkedDeque<E>
67 extends AbstractCollection<E>
68 implements Deque<E>, java.io.Serializable {
69
70 /*
71 * This is an implementation of a concurrent lock-free deque
72 * supporting interior removes but not interior insertions, as
73 * required to support the entire Deque interface.
74 *
75 * We extend the techniques developed for ConcurrentLinkedQueue and
76 * LinkedTransferQueue (see the internal docs for those classes).
77 * Understanding the ConcurrentLinkedQueue implementation is a
78 * prerequisite for understanding the implementation of this class.
79 *
80 * The data structure is a symmetrical doubly-linked "GC-robust"
81 * linked list of nodes. We minimize the number of volatile writes
82 * using two techniques: advancing multiple hops with a single CAS
83 * and mixing volatile and non-volatile writes of the same memory
84 * locations.
85 *
86 * A node contains the expected E ("item") and links to predecessor
87 * ("prev") and successor ("next") nodes:
88 *
89 * class Node<E> { volatile Node<E> prev, next; volatile E item; }
90 *
91 * A node p is considered "live" if it contains a non-null item
92 * (p.item != null). When an item is CASed to null, the item is
93 * atomically logically deleted from the collection.
94 *
95 * At any time, there is precisely one "first" node with a null
96 * prev reference that terminates any chain of prev references
97 * starting at a live node. Similarly there is precisely one
98 * "last" node terminating any chain of next references starting at
99 * a live node. The "first" and "last" nodes may or may not be live.
100 * The "first" and "last" nodes are always mutually reachable.
101 *
102 * A new element is added atomically by CASing the null prev or
103 * next reference in the first or last node to a fresh node
104 * containing the element. The element's node atomically becomes
105 * "live" at that point.
106 *
107 * A node is considered "active" if it is a live node, or the
108 * first or last node. Active nodes cannot be unlinked.
109 *
110 * A "self-link" is a next or prev reference that is the same node:
111 * p.prev == p or p.next == p
112 * Self-links are used in the node unlinking process. Active nodes
113 * never have self-links.
114 *
115 * A node p is active if and only if:
116 *
117 * p.item != null ||
118 * (p.prev == null && p.next != p) ||
119 * (p.next == null && p.prev != p)
120 *
121 * The deque object has two node references, "head" and "tail".
122 * The head and tail are only approximations to the first and last
123 * nodes of the deque. The first node can always be found by
124 * following prev pointers from head; likewise for tail. However,
125 * it is permissible for head and tail to be referring to deleted
126 * nodes that have been unlinked and so may not be reachable from
127 * any live node.
128 *
129 * There are 3 stages of node deletion;
130 * "logical deletion", "unlinking", and "gc-unlinking".
131 *
132 * 1. "logical deletion" by CASing item to null atomically removes
133 * the element from the collection, and makes the containing node
134 * eligible for unlinking.
135 *
136 * 2. "unlinking" makes a deleted node unreachable from active
137 * nodes, and thus eventually reclaimable by GC. Unlinked nodes
138 * may remain reachable indefinitely from an iterator.
139 *
140 * Physical node unlinking is merely an optimization (albeit a
141 * critical one), and so can be performed at our convenience. At
142 * any time, the set of live nodes maintained by prev and next
143 * links are identical, that is, the live nodes found via next
144 * links from the first node is equal to the elements found via
145 * prev links from the last node. However, this is not true for
146 * nodes that have already been logically deleted - such nodes may
147 * be reachable in one direction only.
148 *
149 * 3. "gc-unlinking" takes unlinking further by making active
150 * nodes unreachable from deleted nodes, making it easier for the
151 * GC to reclaim future deleted nodes. This step makes the data
152 * structure "gc-robust", as first described in detail by Boehm
153 * (http://portal.acm.org/citation.cfm?doid=503272.503282).
154 *
155 * GC-unlinked nodes may remain reachable indefinitely from an
156 * iterator, but unlike unlinked nodes, are never reachable from
157 * head or tail.
158 *
159 * Making the data structure GC-robust will eliminate the risk of
160 * unbounded memory retention with conservative GCs and is likely
161 * to improve performance with generational GCs.
162 *
163 * When a node is dequeued at either end, e.g. via poll(), we would
164 * like to break any references from the node to active nodes. We
165 * develop further the use of self-links that was very effective in
166 * other concurrent collection classes. The idea is to replace
167 * prev and next pointers with special values that are interpreted
168 * to mean off-the-list-at-one-end. These are approximations, but
169 * good enough to preserve the properties we want in our
170 * traversals, e.g. we guarantee that a traversal will never visit
171 * the same element twice, but we don't guarantee whether a
172 * traversal that runs out of elements will be able to see more
173 * elements later after enqueues at that end. Doing gc-unlinking
174 * safely is particularly tricky, since any node can be in use
175 * indefinitely (for example by an iterator). We must ensure that
176 * the nodes pointed at by head/tail never get gc-unlinked, since
177 * head/tail are needed to get "back on track" by other nodes that
178 * are gc-unlinked. gc-unlinking accounts for much of the
179 * implementation complexity.
180 *
181 * Since neither unlinking nor gc-unlinking are necessary for
182 * correctness, there are many implementation choices regarding
183 * frequency (eagerness) of these operations. Since volatile
184 * reads are likely to be much cheaper than CASes, saving CASes by
185 * unlinking multiple adjacent nodes at a time may be a win.
186 * gc-unlinking can be performed rarely and still be effective,
187 * since it is most important that long chains of deleted nodes
188 * are occasionally broken.
189 *
190 * The actual representation we use is that p.next == p means to
191 * goto the first node (which in turn is reached by following prev
192 * pointers from head), and p.next == null && p.prev == p means
193 * that the iteration is at an end and that p is a (static final)
194 * dummy node, NEXT_TERMINATOR, and not the last active node.
195 * Finishing the iteration when encountering such a TERMINATOR is
196 * good enough for read-only traversals, so such traversals can use
197 * p.next == null as the termination condition. When we need to
198 * find the last (active) node, for enqueueing a new node, we need
199 * to check whether we have reached a TERMINATOR node; if so,
200 * restart traversal from tail.
201 *
202 * The implementation is completely directionally symmetrical,
203 * except that most public methods that iterate through the list
204 * follow next pointers ("forward" direction).
205 *
206 * We believe (without full proof) that all single-element deque
207 * operations (e.g., addFirst, peekLast, pollLast) are linearizable
208 * (see Herlihy and Shavit's book). However, some combinations of
209 * operations are known not to be linearizable. In particular,
210 * when an addFirst(A) is racing with pollFirst() removing B, it is
211 * possible for an observer iterating over the elements to observe
212 * A B C and subsequently observe A C, even though no interior
213 * removes are ever performed. Nevertheless, iterators behave
214 * reasonably, providing the "weakly consistent" guarantees.
215 *
216 * Empirically, microbenchmarks suggest that this class adds about
217 * 40% overhead relative to ConcurrentLinkedQueue, which feels as
218 * good as we can hope for.
219 */
220
221 private static final long serialVersionUID = 876323262645176354L;
222
223 /**
224 * A node from which the first node on list (that is, the unique node p
225 * with p.prev == null && p.next != p) can be reached in O(1) time.
226 * Invariants:
227 * - the first node is always O(1) reachable from head via prev links
228 * - all live nodes are reachable from the first node via succ()
229 * - head != null
230 * - (tmp = head).next != tmp || tmp != head
231 * - head is never gc-unlinked (but may be unlinked)
232 * Non-invariants:
233 * - head.item may or may not be null
234 * - head may not be reachable from the first or last node, or from tail
235 */
236 private transient volatile Node<E> head;
237
238 /**
239 * A node from which the last node on list (that is, the unique node p
240 * with p.next == null && p.prev != p) can be reached in O(1) time.
241 * Invariants:
242 * - the last node is always O(1) reachable from tail via next links
243 * - all live nodes are reachable from the last node via pred()
244 * - tail != null
245 * - tail is never gc-unlinked (but may be unlinked)
246 * Non-invariants:
247 * - tail.item may or may not be null
248 * - tail may not be reachable from the first or last node, or from head
249 */
250 private transient volatile Node<E> tail;
251
252 private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
253
254 @SuppressWarnings("unchecked")
255 Node<E> prevTerminator() {
256 return (Node<E>) PREV_TERMINATOR;
257 }
258
259 @SuppressWarnings("unchecked")
260 Node<E> nextTerminator() {
261 return (Node<E>) NEXT_TERMINATOR;
262 }
263
264 static final class Node<E> {
265 volatile Node<E> prev;
266 volatile E item;
267 volatile Node<E> next;
268 }
269
270 /**
271 * Returns a new node holding item. Uses relaxed write because item
272 * can only be seen after piggy-backing publication via CAS.
273 */
274 static <E> Node<E> newNode(E item) {
275 Node<E> node = new Node<E>();
276 ITEM.set(node, item);
277 return node;
278 }
279
280 /**
281 * Links e as first element.
282 */
283 private void linkFirst(E e) {
284 final Node<E> newNode = newNode(Objects.requireNonNull(e));
285
286 restartFromHead:
287 for (;;)
288 for (Node<E> h = head, p = h, q;;) {
289 if ((q = p.prev) != null &&
290 (q = (p = q).prev) != null)
291 // Check for head updates every other hop.
292 // If p == q, we are sure to follow head instead.
293 p = (h != (h = head)) ? h : q;
294 else if (p.next == p) // PREV_TERMINATOR
295 continue restartFromHead;
296 else {
297 // p is first node
298 NEXT.set(newNode, p); // CAS piggyback
299 if (PREV.compareAndSet(p, null, newNode)) {
300 // Successful CAS is the linearization point
301 // for e to become an element of this deque,
302 // and for newNode to become "live".
303 if (p != h) // hop two nodes at a time
304 HEAD.compareAndSet(this, h, newNode); // Failure OK.
305 return;
306 }
307 // Lost CAS race to another thread; re-read prev
308 }
309 }
310 }
311
312 /**
313 * Links e as last element.
314 */
315 private void linkLast(E e) {
316 final Node<E> newNode = newNode(Objects.requireNonNull(e));
317
318 restartFromTail:
319 for (;;)
320 for (Node<E> t = tail, p = t, q;;) {
321 if ((q = p.next) != null &&
322 (q = (p = q).next) != null)
323 // Check for tail updates every other hop.
324 // If p == q, we are sure to follow tail instead.
325 p = (t != (t = tail)) ? t : q;
326 else if (p.prev == p) // NEXT_TERMINATOR
327 continue restartFromTail;
328 else {
329 // p is last node
330 PREV.set(newNode, p); // CAS piggyback
331 if (NEXT.compareAndSet(p, null, newNode)) {
332 // Successful CAS is the linearization point
333 // for e to become an element of this deque,
334 // and for newNode to become "live".
335 if (p != t) // hop two nodes at a time
336 TAIL.compareAndSet(this, t, newNode); // Failure OK.
337 return;
338 }
339 // Lost CAS race to another thread; re-read next
340 }
341 }
342 }
343
344 private static final int HOPS = 2;
345
346 /**
347 * Unlinks non-null node x.
348 */
349 void unlink(Node<E> x) {
350 // assert x != null;
351 // assert x.item == null;
352 // assert x != PREV_TERMINATOR;
353 // assert x != NEXT_TERMINATOR;
354
355 final Node<E> prev = x.prev;
356 final Node<E> next = x.next;
357 if (prev == null) {
358 unlinkFirst(x, next);
359 } else if (next == null) {
360 unlinkLast(x, prev);
361 } else {
362 // Unlink interior node.
363 //
364 // This is the common case, since a series of polls at the
365 // same end will be "interior" removes, except perhaps for
366 // the first one, since end nodes cannot be unlinked.
367 //
368 // At any time, all active nodes are mutually reachable by
369 // following a sequence of either next or prev pointers.
370 //
371 // Our strategy is to find the unique active predecessor
372 // and successor of x. Try to fix up their links so that
373 // they point to each other, leaving x unreachable from
374 // active nodes. If successful, and if x has no live
375 // predecessor/successor, we additionally try to gc-unlink,
376 // leaving active nodes unreachable from x, by rechecking
377 // that the status of predecessor and successor are
378 // unchanged and ensuring that x is not reachable from
379 // tail/head, before setting x's prev/next links to their
380 // logical approximate replacements, self/TERMINATOR.
381 Node<E> activePred, activeSucc;
382 boolean isFirst, isLast;
383 int hops = 1;
384
385 // Find active predecessor
386 for (Node<E> p = prev; ; ++hops) {
387 if (p.item != null) {
388 activePred = p;
389 isFirst = false;
390 break;
391 }
392 Node<E> q = p.prev;
393 if (q == null) {
394 if (p.next == p)
395 return;
396 activePred = p;
397 isFirst = true;
398 break;
399 }
400 else if (p == q)
401 return;
402 else
403 p = q;
404 }
405
406 // Find active successor
407 for (Node<E> p = next; ; ++hops) {
408 if (p.item != null) {
409 activeSucc = p;
410 isLast = false;
411 break;
412 }
413 Node<E> q = p.next;
414 if (q == null) {
415 if (p.prev == p)
416 return;
417 activeSucc = p;
418 isLast = true;
419 break;
420 }
421 else if (p == q)
422 return;
423 else
424 p = q;
425 }
426
427 // TODO: better HOP heuristics
428 if (hops < HOPS
429 // always squeeze out interior deleted nodes
430 && (isFirst | isLast))
431 return;
432
433 // Squeeze out deleted nodes between activePred and
434 // activeSucc, including x.
435 skipDeletedSuccessors(activePred);
436 skipDeletedPredecessors(activeSucc);
437
438 // Try to gc-unlink, if possible
439 if ((isFirst | isLast) &&
440
441 // Recheck expected state of predecessor and successor
442 (activePred.next == activeSucc) &&
443 (activeSucc.prev == activePred) &&
444 (isFirst ? activePred.prev == null : activePred.item != null) &&
445 (isLast ? activeSucc.next == null : activeSucc.item != null)) {
446
447 updateHead(); // Ensure x is not reachable from head
448 updateTail(); // Ensure x is not reachable from tail
449
450 // Finally, actually gc-unlink
451 PREV.setRelease(x, isFirst ? prevTerminator() : x);
452 NEXT.setRelease(x, isLast ? nextTerminator() : x);
453 }
454 }
455 }
456
457 /**
458 * Unlinks non-null first node.
459 */
460 private void unlinkFirst(Node<E> first, Node<E> next) {
461 // assert first != null;
462 // assert next != null;
463 // assert first.item == null;
464 for (Node<E> o = null, p = next, q;;) {
465 if (p.item != null || (q = p.next) == null) {
466 if (o != null && p.prev != p &&
467 NEXT.compareAndSet(first, next, p)) {
468 skipDeletedPredecessors(p);
469 if (first.prev == null &&
470 (p.next == null || p.item != null) &&
471 p.prev == first) {
472
473 updateHead(); // Ensure o is not reachable from head
474 updateTail(); // Ensure o is not reachable from tail
475
476 // Finally, actually gc-unlink
477 NEXT.setRelease(o, o);
478 PREV.setRelease(o, prevTerminator());
479 }
480 }
481 return;
482 }
483 else if (p == q)
484 return;
485 else {
486 o = p;
487 p = q;
488 }
489 }
490 }
491
492 /**
493 * Unlinks non-null last node.
494 */
495 private void unlinkLast(Node<E> last, Node<E> prev) {
496 // assert last != null;
497 // assert prev != null;
498 // assert last.item == null;
499 for (Node<E> o = null, p = prev, q;;) {
500 if (p.item != null || (q = p.prev) == null) {
501 if (o != null && p.next != p &&
502 PREV.compareAndSet(last, prev, p)) {
503 skipDeletedSuccessors(p);
504 if (last.next == null &&
505 (p.prev == null || p.item != null) &&
506 p.next == last) {
507
508 updateHead(); // Ensure o is not reachable from head
509 updateTail(); // Ensure o is not reachable from tail
510
511 // Finally, actually gc-unlink
512 PREV.setRelease(o, o);
513 NEXT.setRelease(o, nextTerminator());
514 }
515 }
516 return;
517 }
518 else if (p == q)
519 return;
520 else {
521 o = p;
522 p = q;
523 }
524 }
525 }
526
527 /**
528 * Guarantees that any node which was unlinked before a call to
529 * this method will be unreachable from head after it returns.
530 * Does not guarantee to eliminate slack, only that head will
531 * point to a node that was active while this method was running.
532 */
533 private final void updateHead() {
534 // Either head already points to an active node, or we keep
535 // trying to cas it to the first node until it does.
536 Node<E> h, p, q;
537 restartFromHead:
538 while ((h = head).item == null && (p = h.prev) != null) {
539 for (;;) {
540 if ((q = p.prev) == null ||
541 (q = (p = q).prev) == null) {
542 // It is possible that p is PREV_TERMINATOR,
543 // but if so, the CAS is guaranteed to fail.
544 if (HEAD.compareAndSet(this, h, p))
545 return;
546 else
547 continue restartFromHead;
548 }
549 else if (h != head)
550 continue restartFromHead;
551 else
552 p = q;
553 }
554 }
555 }
556
557 /**
558 * Guarantees that any node which was unlinked before a call to
559 * this method will be unreachable from tail after it returns.
560 * Does not guarantee to eliminate slack, only that tail will
561 * point to a node that was active while this method was running.
562 */
563 private final void updateTail() {
564 // Either tail already points to an active node, or we keep
565 // trying to cas it to the last node until it does.
566 Node<E> t, p, q;
567 restartFromTail:
568 while ((t = tail).item == null && (p = t.next) != null) {
569 for (;;) {
570 if ((q = p.next) == null ||
571 (q = (p = q).next) == null) {
572 // It is possible that p is NEXT_TERMINATOR,
573 // but if so, the CAS is guaranteed to fail.
574 if (TAIL.compareAndSet(this, t, p))
575 return;
576 else
577 continue restartFromTail;
578 }
579 else if (t != tail)
580 continue restartFromTail;
581 else
582 p = q;
583 }
584 }
585 }
586
587 private void skipDeletedPredecessors(Node<E> x) {
588 whileActive:
589 do {
590 Node<E> prev = x.prev;
591 // assert prev != null;
592 // assert x != NEXT_TERMINATOR;
593 // assert x != PREV_TERMINATOR;
594 Node<E> p = prev;
595 findActive:
596 for (;;) {
597 if (p.item != null)
598 break findActive;
599 Node<E> q = p.prev;
600 if (q == null) {
601 if (p.next == p)
602 continue whileActive;
603 break findActive;
604 }
605 else if (p == q)
606 continue whileActive;
607 else
608 p = q;
609 }
610
611 // found active CAS target
612 if (prev == p || PREV.compareAndSet(x, prev, p))
613 return;
614
615 } while (x.item != null || x.next == null);
616 }
617
618 private void skipDeletedSuccessors(Node<E> x) {
619 whileActive:
620 do {
621 Node<E> next = x.next;
622 // assert next != null;
623 // assert x != NEXT_TERMINATOR;
624 // assert x != PREV_TERMINATOR;
625 Node<E> p = next;
626 findActive:
627 for (;;) {
628 if (p.item != null)
629 break findActive;
630 Node<E> q = p.next;
631 if (q == null) {
632 if (p.prev == p)
633 continue whileActive;
634 break findActive;
635 }
636 else if (p == q)
637 continue whileActive;
638 else
639 p = q;
640 }
641
642 // found active CAS target
643 if (next == p || NEXT.compareAndSet(x, next, p))
644 return;
645
646 } while (x.item != null || x.prev == null);
647 }
648
649 /**
650 * Returns the successor of p, or the first node if p.next has been
651 * linked to self, which will only be true if traversing with a
652 * stale pointer that is now off the list.
653 */
654 final Node<E> succ(Node<E> p) {
655 // TODO: should we skip deleted nodes here?
656 Node<E> q = p.next;
657 return (p == q) ? first() : q;
658 }
659
660 /**
661 * Returns the predecessor of p, or the last node if p.prev has been
662 * linked to self, which will only be true if traversing with a
663 * stale pointer that is now off the list.
664 */
665 final Node<E> pred(Node<E> p) {
666 Node<E> q = p.prev;
667 return (p == q) ? last() : q;
668 }
669
670 /**
671 * Returns the first node, the unique node p for which:
672 * p.prev == null && p.next != p
673 * The returned node may or may not be logically deleted.
674 * Guarantees that head is set to the returned node.
675 */
676 Node<E> first() {
677 restartFromHead:
678 for (;;)
679 for (Node<E> h = head, p = h, q;;) {
680 if ((q = p.prev) != null &&
681 (q = (p = q).prev) != null)
682 // Check for head updates every other hop.
683 // If p == q, we are sure to follow head instead.
684 p = (h != (h = head)) ? h : q;
685 else if (p == h
686 // It is possible that p is PREV_TERMINATOR,
687 // but if so, the CAS is guaranteed to fail.
688 || HEAD.compareAndSet(this, h, p))
689 return p;
690 else
691 continue restartFromHead;
692 }
693 }
694
695 /**
696 * Returns the last node, the unique node p for which:
697 * p.next == null && p.prev != p
698 * The returned node may or may not be logically deleted.
699 * Guarantees that tail is set to the returned node.
700 */
701 Node<E> last() {
702 restartFromTail:
703 for (;;)
704 for (Node<E> t = tail, p = t, q;;) {
705 if ((q = p.next) != null &&
706 (q = (p = q).next) != null)
707 // Check for tail updates every other hop.
708 // If p == q, we are sure to follow tail instead.
709 p = (t != (t = tail)) ? t : q;
710 else if (p == t
711 // It is possible that p is NEXT_TERMINATOR,
712 // but if so, the CAS is guaranteed to fail.
713 || TAIL.compareAndSet(this, t, p))
714 return p;
715 else
716 continue restartFromTail;
717 }
718 }
719
720 // Minor convenience utilities
721
722 /**
723 * Returns element unless it is null, in which case throws
724 * NoSuchElementException.
725 *
726 * @param v the element
727 * @return the element
728 */
729 private E screenNullResult(E v) {
730 if (v == null)
731 throw new NoSuchElementException();
732 return v;
733 }
734
735 /**
736 * Constructs an empty deque.
737 */
738 public ConcurrentLinkedDeque() {
739 head = tail = new Node<E>();
740 }
741
742 /**
743 * Constructs a deque initially containing the elements of
744 * the given collection, added in traversal order of the
745 * collection's iterator.
746 *
747 * @param c the collection of elements to initially contain
748 * @throws NullPointerException if the specified collection or any
749 * of its elements are null
750 */
751 public ConcurrentLinkedDeque(Collection<? extends E> c) {
752 // Copy c into a private chain of Nodes
753 Node<E> h = null, t = null;
754 for (E e : c) {
755 Node<E> newNode = newNode(Objects.requireNonNull(e));
756 if (h == null)
757 h = t = newNode;
758 else {
759 NEXT.set(t, newNode);
760 PREV.set(newNode, t);
761 t = newNode;
762 }
763 }
764 initHeadTail(h, t);
765 }
766
767 /**
768 * Initializes head and tail, ensuring invariants hold.
769 */
770 private void initHeadTail(Node<E> h, Node<E> t) {
771 if (h == t) {
772 if (h == null)
773 h = t = new Node<E>();
774 else {
775 // Avoid edge case of a single Node with non-null item.
776 Node<E> newNode = new Node<E>();
777 NEXT.set(t, newNode);
778 PREV.set(newNode, t);
779 t = newNode;
780 }
781 }
782 head = h;
783 tail = t;
784 }
785
786 /**
787 * Inserts the specified element at the front of this deque.
788 * As the deque is unbounded, this method will never throw
789 * {@link IllegalStateException}.
790 *
791 * @throws NullPointerException if the specified element is null
792 */
793 public void addFirst(E e) {
794 linkFirst(e);
795 }
796
797 /**
798 * Inserts the specified element at the end of this deque.
799 * As the deque is unbounded, this method will never throw
800 * {@link IllegalStateException}.
801 *
802 * <p>This method is equivalent to {@link #add}.
803 *
804 * @throws NullPointerException if the specified element is null
805 */
806 public void addLast(E e) {
807 linkLast(e);
808 }
809
810 /**
811 * Inserts the specified element at the front of this deque.
812 * As the deque is unbounded, this method will never return {@code false}.
813 *
814 * @return {@code true} (as specified by {@link Deque#offerFirst})
815 * @throws NullPointerException if the specified element is null
816 */
817 public boolean offerFirst(E e) {
818 linkFirst(e);
819 return true;
820 }
821
822 /**
823 * Inserts the specified element at the end of this deque.
824 * As the deque is unbounded, this method will never return {@code false}.
825 *
826 * <p>This method is equivalent to {@link #add}.
827 *
828 * @return {@code true} (as specified by {@link Deque#offerLast})
829 * @throws NullPointerException if the specified element is null
830 */
831 public boolean offerLast(E e) {
832 linkLast(e);
833 return true;
834 }
835
836 public E peekFirst() {
837 for (Node<E> p = first(); p != null; p = succ(p)) {
838 E item = p.item;
839 if (item != null)
840 return item;
841 }
842 return null;
843 }
844
845 public E peekLast() {
846 for (Node<E> p = last(); p != null; p = pred(p)) {
847 E item = p.item;
848 if (item != null)
849 return item;
850 }
851 return null;
852 }
853
854 /**
855 * @throws NoSuchElementException {@inheritDoc}
856 */
857 public E getFirst() {
858 return screenNullResult(peekFirst());
859 }
860
861 /**
862 * @throws NoSuchElementException {@inheritDoc}
863 */
864 public E getLast() {
865 return screenNullResult(peekLast());
866 }
867
868 public E pollFirst() {
869 for (Node<E> p = first(); p != null; p = succ(p)) {
870 E item = p.item;
871 if (item != null && ITEM.compareAndSet(p, item, null)) {
872 unlink(p);
873 return item;
874 }
875 }
876 return null;
877 }
878
879 public E pollLast() {
880 for (Node<E> p = last(); p != null; p = pred(p)) {
881 E item = p.item;
882 if (item != null && ITEM.compareAndSet(p, item, null)) {
883 unlink(p);
884 return item;
885 }
886 }
887 return null;
888 }
889
890 /**
891 * @throws NoSuchElementException {@inheritDoc}
892 */
893 public E removeFirst() {
894 return screenNullResult(pollFirst());
895 }
896
897 /**
898 * @throws NoSuchElementException {@inheritDoc}
899 */
900 public E removeLast() {
901 return screenNullResult(pollLast());
902 }
903
904 // *** Queue and stack methods ***
905
906 /**
907 * Inserts the specified element at the tail of this deque.
908 * As the deque is unbounded, this method will never return {@code false}.
909 *
910 * @return {@code true} (as specified by {@link Queue#offer})
911 * @throws NullPointerException if the specified element is null
912 */
913 public boolean offer(E e) {
914 return offerLast(e);
915 }
916
917 /**
918 * Inserts the specified element at the tail of this deque.
919 * As the deque is unbounded, this method will never throw
920 * {@link IllegalStateException} or return {@code false}.
921 *
922 * @return {@code true} (as specified by {@link Collection#add})
923 * @throws NullPointerException if the specified element is null
924 */
925 public boolean add(E e) {
926 return offerLast(e);
927 }
928
929 public E poll() { return pollFirst(); }
930 public E peek() { return peekFirst(); }
931
932 /**
933 * @throws NoSuchElementException {@inheritDoc}
934 */
935 public E remove() { return removeFirst(); }
936
937 /**
938 * @throws NoSuchElementException {@inheritDoc}
939 */
940 public E pop() { return removeFirst(); }
941
942 /**
943 * @throws NoSuchElementException {@inheritDoc}
944 */
945 public E element() { return getFirst(); }
946
947 /**
948 * @throws NullPointerException {@inheritDoc}
949 */
950 public void push(E e) { addFirst(e); }
951
952 /**
953 * Removes the first occurrence of the specified element from this deque.
954 * If the deque does not contain the element, it is unchanged.
955 * More formally, removes the first element {@code e} such that
956 * {@code o.equals(e)} (if such an element exists).
957 * Returns {@code true} if this deque contained the specified element
958 * (or equivalently, if this deque changed as a result of the call).
959 *
960 * @param o element to be removed from this deque, if present
961 * @return {@code true} if the deque contained the specified element
962 * @throws NullPointerException if the specified element is null
963 */
964 public boolean removeFirstOccurrence(Object o) {
965 Objects.requireNonNull(o);
966 for (Node<E> p = first(); p != null; p = succ(p)) {
967 E item = p.item;
968 if (item != null && o.equals(item) &&
969 ITEM.compareAndSet(p, item, null)) {
970 unlink(p);
971 return true;
972 }
973 }
974 return false;
975 }
976
977 /**
978 * Removes the last occurrence of the specified element from this deque.
979 * If the deque does not contain the element, it is unchanged.
980 * More formally, removes the last element {@code e} such that
981 * {@code o.equals(e)} (if such an element exists).
982 * Returns {@code true} if this deque contained the specified element
983 * (or equivalently, if this deque changed as a result of the call).
984 *
985 * @param o element to be removed from this deque, if present
986 * @return {@code true} if the deque contained the specified element
987 * @throws NullPointerException if the specified element is null
988 */
989 public boolean removeLastOccurrence(Object o) {
990 Objects.requireNonNull(o);
991 for (Node<E> p = last(); p != null; p = pred(p)) {
992 E item = p.item;
993 if (item != null && o.equals(item) &&
994 ITEM.compareAndSet(p, item, null)) {
995 unlink(p);
996 return true;
997 }
998 }
999 return false;
1000 }
1001
1002 /**
1003 * Returns {@code true} if this deque contains the specified element.
1004 * More formally, returns {@code true} if and only if this deque contains
1005 * at least one element {@code e} such that {@code o.equals(e)}.
1006 *
1007 * @param o element whose presence in this deque is to be tested
1008 * @return {@code true} if this deque contains the specified element
1009 */
1010 public boolean contains(Object o) {
1011 if (o != null) {
1012 for (Node<E> p = first(); p != null; p = succ(p)) {
1013 E item = p.item;
1014 if (item != null && o.equals(item))
1015 return true;
1016 }
1017 }
1018 return false;
1019 }
1020
1021 /**
1022 * Returns {@code true} if this collection contains no elements.
1023 *
1024 * @return {@code true} if this collection contains no elements
1025 */
1026 public boolean isEmpty() {
1027 return peekFirst() == null;
1028 }
1029
1030 /**
1031 * Returns the number of elements in this deque. If this deque
1032 * contains more than {@code Integer.MAX_VALUE} elements, it
1033 * returns {@code Integer.MAX_VALUE}.
1034 *
1035 * <p>Beware that, unlike in most collections, this method is
1036 * <em>NOT</em> a constant-time operation. Because of the
1037 * asynchronous nature of these deques, determining the current
1038 * number of elements requires traversing them all to count them.
1039 * Additionally, it is possible for the size to change during
1040 * execution of this method, in which case the returned result
1041 * will be inaccurate. Thus, this method is typically not very
1042 * useful in concurrent applications.
1043 *
1044 * @return the number of elements in this deque
1045 */
1046 public int size() {
1047 restartFromHead: for (;;) {
1048 int count = 0;
1049 for (Node<E> p = first(); p != null;) {
1050 if (p.item != null)
1051 if (++count == Integer.MAX_VALUE)
1052 break; // @see Collection.size()
1053 if (p == (p = p.next))
1054 continue restartFromHead;
1055 }
1056 return count;
1057 }
1058 }
1059
1060 /**
1061 * Removes the first occurrence of the specified element from this deque.
1062 * If the deque does not contain the element, it is unchanged.
1063 * More formally, removes the first element {@code e} such that
1064 * {@code o.equals(e)} (if such an element exists).
1065 * Returns {@code true} if this deque contained the specified element
1066 * (or equivalently, if this deque changed as a result of the call).
1067 *
1068 * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
1069 *
1070 * @param o element to be removed from this deque, if present
1071 * @return {@code true} if the deque contained the specified element
1072 * @throws NullPointerException if the specified element is null
1073 */
1074 public boolean remove(Object o) {
1075 return removeFirstOccurrence(o);
1076 }
1077
1078 /**
1079 * Appends all of the elements in the specified collection to the end of
1080 * this deque, in the order that they are returned by the specified
1081 * collection's iterator. Attempts to {@code addAll} of a deque to
1082 * itself result in {@code IllegalArgumentException}.
1083 *
1084 * @param c the elements to be inserted into this deque
1085 * @return {@code true} if this deque changed as a result of the call
1086 * @throws NullPointerException if the specified collection or any
1087 * of its elements are null
1088 * @throws IllegalArgumentException if the collection is this deque
1089 */
1090 public boolean addAll(Collection<? extends E> c) {
1091 if (c == this)
1092 // As historically specified in AbstractQueue#addAll
1093 throw new IllegalArgumentException();
1094
1095 // Copy c into a private chain of Nodes
1096 Node<E> beginningOfTheEnd = null, last = null;
1097 for (E e : c) {
1098 Node<E> newNode = newNode(Objects.requireNonNull(e));
1099 if (beginningOfTheEnd == null)
1100 beginningOfTheEnd = last = newNode;
1101 else {
1102 NEXT.set(last, newNode);
1103 PREV.set(newNode, last);
1104 last = newNode;
1105 }
1106 }
1107 if (beginningOfTheEnd == null)
1108 return false;
1109
1110 // Atomically append the chain at the tail of this collection
1111 restartFromTail:
1112 for (;;)
1113 for (Node<E> t = tail, p = t, q;;) {
1114 if ((q = p.next) != null &&
1115 (q = (p = q).next) != null)
1116 // Check for tail updates every other hop.
1117 // If p == q, we are sure to follow tail instead.
1118 p = (t != (t = tail)) ? t : q;
1119 else if (p.prev == p) // NEXT_TERMINATOR
1120 continue restartFromTail;
1121 else {
1122 // p is last node
1123 PREV.set(beginningOfTheEnd, p); // CAS piggyback
1124 if (NEXT.compareAndSet(p, null, beginningOfTheEnd)) {
1125 // Successful CAS is the linearization point
1126 // for all elements to be added to this deque.
1127 if (!TAIL.compareAndSet(this, t, last)) {
1128 // Try a little harder to update tail,
1129 // since we may be adding many elements.
1130 t = tail;
1131 if (last.next == null)
1132 TAIL.compareAndSet(this, t, last);
1133 }
1134 return true;
1135 }
1136 // Lost CAS race to another thread; re-read next
1137 }
1138 }
1139 }
1140
1141 /**
1142 * Removes all of the elements from this deque.
1143 */
1144 public void clear() {
1145 while (pollFirst() != null)
1146 ;
1147 }
1148
1149 public String toString() {
1150 String[] a = null;
1151 restartFromHead: for (;;) {
1152 int charLength = 0;
1153 int size = 0;
1154 for (Node<E> p = first(); p != null;) {
1155 E item = p.item;
1156 if (item != null) {
1157 if (a == null)
1158 a = new String[4];
1159 else if (size == a.length)
1160 a = Arrays.copyOf(a, 2 * size);
1161 String s = item.toString();
1162 a[size++] = s;
1163 charLength += s.length();
1164 }
1165 if (p == (p = p.next))
1166 continue restartFromHead;
1167 }
1168
1169 if (size == 0)
1170 return "[]";
1171
1172 return Helpers.toString(a, size, charLength);
1173 }
1174 }
1175
1176 private Object[] toArrayInternal(Object[] a) {
1177 Object[] x = a;
1178 restartFromHead: for (;;) {
1179 int size = 0;
1180 for (Node<E> p = first(); p != null;) {
1181 E item = p.item;
1182 if (item != null) {
1183 if (x == null)
1184 x = new Object[4];
1185 else if (size == x.length)
1186 x = Arrays.copyOf(x, 2 * (size + 4));
1187 x[size++] = item;
1188 }
1189 if (p == (p = p.next))
1190 continue restartFromHead;
1191 }
1192 if (x == null)
1193 return new Object[0];
1194 else if (a != null && size <= a.length) {
1195 if (a != x)
1196 System.arraycopy(x, 0, a, 0, size);
1197 if (size < a.length)
1198 a[size] = null;
1199 return a;
1200 }
1201 return (size == x.length) ? x : Arrays.copyOf(x, size);
1202 }
1203 }
1204
1205 /**
1206 * Returns an array containing all of the elements in this deque, in
1207 * proper sequence (from first to last element).
1208 *
1209 * <p>The returned array will be "safe" in that no references to it are
1210 * maintained by this deque. (In other words, this method must allocate
1211 * a new array). The caller is thus free to modify the returned array.
1212 *
1213 * <p>This method acts as bridge between array-based and collection-based
1214 * APIs.
1215 *
1216 * @return an array containing all of the elements in this deque
1217 */
1218 public Object[] toArray() {
1219 return toArrayInternal(null);
1220 }
1221
1222 /**
1223 * Returns an array containing all of the elements in this deque,
1224 * in proper sequence (from first to last element); the runtime
1225 * type of the returned array is that of the specified array. If
1226 * the deque fits in the specified array, it is returned therein.
1227 * Otherwise, a new array is allocated with the runtime type of
1228 * the specified array and the size of this deque.
1229 *
1230 * <p>If this deque fits in the specified array with room to spare
1231 * (i.e., the array has more elements than this deque), the element in
1232 * the array immediately following the end of the deque is set to
1233 * {@code null}.
1234 *
1235 * <p>Like the {@link #toArray()} method, this method acts as
1236 * bridge between array-based and collection-based APIs. Further,
1237 * this method allows precise control over the runtime type of the
1238 * output array, and may, under certain circumstances, be used to
1239 * save allocation costs.
1240 *
1241 * <p>Suppose {@code x} is a deque known to contain only strings.
1242 * The following code can be used to dump the deque into a newly
1243 * allocated array of {@code String}:
1244 *
1245 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
1246 *
1247 * Note that {@code toArray(new Object[0])} is identical in function to
1248 * {@code toArray()}.
1249 *
1250 * @param a the array into which the elements of the deque are to
1251 * be stored, if it is big enough; otherwise, a new array of the
1252 * same runtime type is allocated for this purpose
1253 * @return an array containing all of the elements in this deque
1254 * @throws ArrayStoreException if the runtime type of the specified array
1255 * is not a supertype of the runtime type of every element in
1256 * this deque
1257 * @throws NullPointerException if the specified array is null
1258 */
1259 @SuppressWarnings("unchecked")
1260 public <T> T[] toArray(T[] a) {
1261 if (a == null) throw new NullPointerException();
1262 return (T[]) toArrayInternal(a);
1263 }
1264
1265 /**
1266 * Returns an iterator over the elements in this deque in proper sequence.
1267 * The elements will be returned in order from first (head) to last (tail).
1268 *
1269 * <p>The returned iterator is
1270 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1271 *
1272 * @return an iterator over the elements in this deque in proper sequence
1273 */
1274 public Iterator<E> iterator() {
1275 return new Itr();
1276 }
1277
1278 /**
1279 * Returns an iterator over the elements in this deque in reverse
1280 * sequential order. The elements will be returned in order from
1281 * last (tail) to first (head).
1282 *
1283 * <p>The returned iterator is
1284 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1285 *
1286 * @return an iterator over the elements in this deque in reverse order
1287 */
1288 public Iterator<E> descendingIterator() {
1289 return new DescendingItr();
1290 }
1291
1292 private abstract class AbstractItr implements Iterator<E> {
1293 /**
1294 * Next node to return item for.
1295 */
1296 private Node<E> nextNode;
1297
1298 /**
1299 * nextItem holds on to item fields because once we claim
1300 * that an element exists in hasNext(), we must return it in
1301 * the following next() call even if it was in the process of
1302 * being removed when hasNext() was called.
1303 */
1304 private E nextItem;
1305
1306 /**
1307 * Node returned by most recent call to next. Needed by remove.
1308 * Reset to null if this element is deleted by a call to remove.
1309 */
1310 private Node<E> lastRet;
1311
1312 abstract Node<E> startNode();
1313 abstract Node<E> nextNode(Node<E> p);
1314
1315 AbstractItr() {
1316 advance();
1317 }
1318
1319 /**
1320 * Sets nextNode and nextItem to next valid node, or to null
1321 * if no such.
1322 */
1323 private void advance() {
1324 lastRet = nextNode;
1325
1326 Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
1327 for (;; p = nextNode(p)) {
1328 if (p == null) {
1329 // might be at active end or TERMINATOR node; both are OK
1330 nextNode = null;
1331 nextItem = null;
1332 break;
1333 }
1334 E item = p.item;
1335 if (item != null) {
1336 nextNode = p;
1337 nextItem = item;
1338 break;
1339 }
1340 }
1341 }
1342
1343 public boolean hasNext() {
1344 return nextItem != null;
1345 }
1346
1347 public E next() {
1348 E item = nextItem;
1349 if (item == null) throw new NoSuchElementException();
1350 advance();
1351 return item;
1352 }
1353
1354 public void remove() {
1355 Node<E> l = lastRet;
1356 if (l == null) throw new IllegalStateException();
1357 l.item = null;
1358 unlink(l);
1359 lastRet = null;
1360 }
1361 }
1362
1363 /** Forward iterator */
1364 private class Itr extends AbstractItr {
1365 Node<E> startNode() { return first(); }
1366 Node<E> nextNode(Node<E> p) { return succ(p); }
1367 }
1368
1369 /** Descending iterator */
1370 private class DescendingItr extends AbstractItr {
1371 Node<E> startNode() { return last(); }
1372 Node<E> nextNode(Node<E> p) { return pred(p); }
1373 }
1374
1375 /** A customized variant of Spliterators.IteratorSpliterator */
1376 static final class CLDSpliterator<E> implements Spliterator<E> {
1377 static final int MAX_BATCH = 1 << 25; // max batch array size;
1378 final ConcurrentLinkedDeque<E> queue;
1379 Node<E> current; // current node; null until initialized
1380 int batch; // batch size for splits
1381 boolean exhausted; // true when no more nodes
1382 CLDSpliterator(ConcurrentLinkedDeque<E> queue) {
1383 this.queue = queue;
1384 }
1385
1386 public Spliterator<E> trySplit() {
1387 Node<E> p;
1388 final ConcurrentLinkedDeque<E> q = this.queue;
1389 int b = batch;
1390 int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
1391 if (!exhausted &&
1392 ((p = current) != null || (p = q.first()) != null)) {
1393 if (p.item == null && p == (p = p.next))
1394 current = p = q.first();
1395 if (p != null && p.next != null) {
1396 Object[] a = new Object[n];
1397 int i = 0;
1398 do {
1399 if ((a[i] = p.item) != null)
1400 ++i;
1401 if (p == (p = p.next))
1402 p = q.first();
1403 } while (p != null && i < n);
1404 if ((current = p) == null)
1405 exhausted = true;
1406 if (i > 0) {
1407 batch = i;
1408 return Spliterators.spliterator
1409 (a, 0, i, (Spliterator.ORDERED |
1410 Spliterator.NONNULL |
1411 Spliterator.CONCURRENT));
1412 }
1413 }
1414 }
1415 return null;
1416 }
1417
1418 public void forEachRemaining(Consumer<? super E> action) {
1419 Node<E> p;
1420 if (action == null) throw new NullPointerException();
1421 final ConcurrentLinkedDeque<E> q = this.queue;
1422 if (!exhausted &&
1423 ((p = current) != null || (p = q.first()) != null)) {
1424 exhausted = true;
1425 do {
1426 E e = p.item;
1427 if (p == (p = p.next))
1428 p = q.first();
1429 if (e != null)
1430 action.accept(e);
1431 } while (p != null);
1432 }
1433 }
1434
1435 public boolean tryAdvance(Consumer<? super E> action) {
1436 Node<E> p;
1437 if (action == null) throw new NullPointerException();
1438 final ConcurrentLinkedDeque<E> q = this.queue;
1439 if (!exhausted &&
1440 ((p = current) != null || (p = q.first()) != null)) {
1441 E e;
1442 do {
1443 e = p.item;
1444 if (p == (p = p.next))
1445 p = q.first();
1446 } while (e == null && p != null);
1447 if ((current = p) == null)
1448 exhausted = true;
1449 if (e != null) {
1450 action.accept(e);
1451 return true;
1452 }
1453 }
1454 return false;
1455 }
1456
1457 public long estimateSize() { return Long.MAX_VALUE; }
1458
1459 public int characteristics() {
1460 return Spliterator.ORDERED | Spliterator.NONNULL |
1461 Spliterator.CONCURRENT;
1462 }
1463 }
1464
1465 /**
1466 * Returns a {@link Spliterator} over the elements in this deque.
1467 *
1468 * <p>The returned spliterator is
1469 * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1470 *
1471 * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
1472 * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
1473 *
1474 * @implNote
1475 * The {@code Spliterator} implements {@code trySplit} to permit limited
1476 * parallelism.
1477 *
1478 * @return a {@code Spliterator} over the elements in this deque
1479 * @since 1.8
1480 */
1481 public Spliterator<E> spliterator() {
1482 return new CLDSpliterator<E>(this);
1483 }
1484
1485 /**
1486 * Saves this deque to a stream (that is, serializes it).
1487 *
1488 * @param s the stream
1489 * @throws java.io.IOException if an I/O error occurs
1490 * @serialData All of the elements (each an {@code E}) in
1491 * the proper order, followed by a null
1492 */
1493 private void writeObject(java.io.ObjectOutputStream s)
1494 throws java.io.IOException {
1495
1496 // Write out any hidden stuff
1497 s.defaultWriteObject();
1498
1499 // Write out all elements in the proper order.
1500 for (Node<E> p = first(); p != null; p = succ(p)) {
1501 E item = p.item;
1502 if (item != null)
1503 s.writeObject(item);
1504 }
1505
1506 // Use trailing null as sentinel
1507 s.writeObject(null);
1508 }
1509
1510 /**
1511 * Reconstitutes this deque from a stream (that is, deserializes it).
1512 * @param s the stream
1513 * @throws ClassNotFoundException if the class of a serialized object
1514 * could not be found
1515 * @throws java.io.IOException if an I/O error occurs
1516 */
1517 private void readObject(java.io.ObjectInputStream s)
1518 throws java.io.IOException, ClassNotFoundException {
1519 s.defaultReadObject();
1520
1521 // Read in elements until trailing null sentinel found
1522 Node<E> h = null, t = null;
1523 for (Object item; (item = s.readObject()) != null; ) {
1524 @SuppressWarnings("unchecked")
1525 Node<E> newNode = newNode((E) item);
1526 if (h == null)
1527 h = t = newNode;
1528 else {
1529 NEXT.set(t, newNode);
1530 PREV.set(newNode, t);
1531 t = newNode;
1532 }
1533 }
1534 initHeadTail(h, t);
1535 }
1536
1537 // VarHandle mechanics
1538 private static final VarHandle HEAD;
1539 private static final VarHandle TAIL;
1540 private static final VarHandle PREV;
1541 private static final VarHandle NEXT;
1542 private static final VarHandle ITEM;
1543 static {
1544 PREV_TERMINATOR = new Node<Object>();
1545 PREV_TERMINATOR.next = PREV_TERMINATOR;
1546 NEXT_TERMINATOR = new Node<Object>();
1547 NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
1548 try {
1549 MethodHandles.Lookup l = MethodHandles.lookup();
1550 HEAD = l.findVarHandle(ConcurrentLinkedDeque.class, "head",
1551 Node.class);
1552 TAIL = l.findVarHandle(ConcurrentLinkedDeque.class, "tail",
1553 Node.class);
1554 PREV = l.findVarHandle(Node.class, "prev", Node.class);
1555 NEXT = l.findVarHandle(Node.class, "next", Node.class);
1556 ITEM = l.findVarHandle(Node.class, "item", Object.class);
1557 } catch (ReflectiveOperationException e) {
1558 throw new Error(e);
1559 }
1560 }
1561 }