for (E e : c) { checkNotNull(e); Node<E> newNode = new Node<E>(e); if (beginningOfTheEnd == null) beginningOfTheEnd = last = newNode; else { last.lazySetNext(newNode); newNode.lazySetPrev(last); last = newNode; else { beginningOfTheEnd.lazySetPrev(p); // CAS piggyback if (p.casNext(null, beginningOfTheEnd)) {
/** * Removes the first element {@code e} such that * {@code o.equals(e)}, if such an element exists in this deque. * If the deque does not contain the element, it is unchanged. * * @param o element to be removed from this deque, if present * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ public boolean removeFirstOccurrence(Object o) { checkNotNull(o); for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null && o.equals(item) && p.casItem(item, null)) { unlink(p); return true; } } return false; }
x.lazySetPrev(isFirst ? prevTerminator() : x); x.lazySetNext(isLast ? nextTerminator() : x);
if (o != null && p.prev != p && first.casNext(next, p)) { skipDeletedPredecessors(p); if (first.prev == null && o.lazySetNext(o); o.lazySetPrev(prevTerminator());
final Node<E> newNode = new Node<E>(e); else { newNode.lazySetPrev(p); // CAS piggyback if (p.casNext(null, newNode)) {
private void skipDeletedSuccessors(Node<E> x) { whileActive: do { Node<E> next = x.next; // assert next != null; // assert x != NEXT_TERMINATOR; // assert x != PREV_TERMINATOR; Node<E> p = next; findActive: for (;;) { if (p.item != null) break findActive; Node<E> q = p.next; if (q == null) { if (p.prev == p) continue whileActive; break findActive; } else if (p == q) continue whileActive; else p = q; } // found active CAS target if (next == p || x.casNext(next, p)) return; } while (x.item != null || x.prev == null); }
if (o != null && p.next != p && last.casPrev(prev, p)) { skipDeletedSuccessors(p); if (last.next == null && o.lazySetPrev(o); o.lazySetNext(nextTerminator());
final Node<E> newNode = new Node<E>(e); else { newNode.lazySetNext(p); // CAS piggyback if (p.casPrev(null, newNode)) {
private void skipDeletedPredecessors(Node<E> x) { whileActive: do { Node<E> prev = x.prev; // assert prev != null; // assert x != NEXT_TERMINATOR; // assert x != PREV_TERMINATOR; Node<E> p = prev; findActive: for (;;) { if (p.item != null) break findActive; Node<E> q = p.prev; if (q == null) { if (p.next == p) continue whileActive; break findActive; } else if (p == q) continue whileActive; else p = q; } // found active CAS target if (prev == p || x.casPrev(prev, p)) return; } while (x.item != null || x.next == null); }
/** * Constructs a deque initially containing the elements of * the given collection, added in traversal order of the * collection's iterator. * * @param c the collection of elements to initially contain * @throws NullPointerException if the specified collection or any * of its elements are null */ public ConcurrentLinkedDeque(Collection<? extends E> c) { // Copy c into a private chain of Nodes Node<E> h = null, t = null; for (E e : c) { checkNotNull(e); Node<E> newNode = new Node<E>(e); if (h == null) h = t = newNode; else { t.lazySetNext(newNode); newNode.lazySetPrev(t); t = newNode; } } initHeadTail(h, t); }
/** * Reconstitutes the instance from a stream (that is, deserializes it). * @param s the stream */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); // Read in elements until trailing null sentinel found Node<E> h = null, t = null; Object item; while ((item = s.readObject()) != null) { @SuppressWarnings("unchecked") Node<E> newNode = new Node<E>((E) item); if (h == null) h = t = newNode; else { t.lazySetNext(newNode); newNode.lazySetPrev(t); t = newNode; } } initHeadTail(h, t); }
/** * Removes the last element {@code e} such that * {@code o.equals(e)}, if such an element exists in this deque. * If the deque does not contain the element, it is unchanged. * * @param o element to be removed from this deque, if present * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ public boolean removeLastOccurrence(Object o) { checkNotNull(o); for (Node<E> p = last(); p != null; p = pred(p)) { E item = p.item; if (item != null && o.equals(item) && p.casItem(item, null)) { unlink(p); return true; } } return false; }
/** * Initializes head and tail, ensuring invariants hold. */ private void initHeadTail(Node<E> h, Node<E> t) { if (h == t) { if (h == null) h = t = new Node<E>(null); else { // Avoid edge case of a single Node with non-null item. Node<E> newNode = new Node<E>(null); t.lazySetNext(newNode); newNode.lazySetPrev(t); t = newNode; } } head = h; tail = t; }
/** * Constructs an empty deque. */ public ConcurrentLinkedDeque() { head = tail = new Node<E>(null); }
public E pollLast() { for (Node<E> p = last(); p != null; p = pred(p)) { E item = p.item; if (item != null && p.casItem(item, null)) { unlink(p); return item; } } return null; }
public E pollFirst() { for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null && p.casItem(item, null)) { unlink(p); return item; } } return null; }