public void push(E e) { addFirst(e); } public E pop() { return removeFirst(); }
/** * Returns the first node, the unique node p for which: * p.prev == null && p.next != p * The returned node may or may not be logically deleted. * Guarantees that head is set to the returned node. */ Node<E> first() { restartFromHead: for (;;) for (Node<E> h = head, p = h, q;;) { if ((q = p.prev) != null && (q = (p = q).prev) != null) // Check for head updates every other hop. // If p == q, we are sure to follow head instead. p = (h != (h = head)) ? h : q; else if (p == h // It is possible that p is PREV_TERMINATOR, // but if so, the CAS is guaranteed to fail. || casHead(h, p)) return p; else continue restartFromHead; } }
/** * Returns the last node, the unique node p for which: * p.next == null && p.prev != p * The returned node may or may not be logically deleted. * Guarantees that tail is set to the returned node. */ Node<E> last() { restartFromTail: for (;;) for (Node<E> t = tail, p = t, q;;) { if ((q = p.next) != null && (q = (p = q).next) != null) // Check for tail updates every other hop. // If p == q, we are sure to follow tail instead. p = (t != (t = tail)) ? t : q; else if (p == t // It is possible that p is NEXT_TERMINATOR, // but if so, the CAS is guaranteed to fail. || casTail(t, p)) return p; else continue restartFromTail; } }
/** * 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; }
/** * 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; }
checkNotNull(e); final Node<E> newNode = new Node<E>(e); casTail(t, newNode); // Failure is OK. return;
/** * 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); }
checkNotNull(e); final Node<E> newNode = new Node<E>(e); casHead(h, newNode); // Failure is OK. return;
/** * Inserts the specified element at the front of this deque. * As the deque is unbounded, this method will never throw * {@link IllegalStateException}. * * @throws NullPointerException if the specified element is null */ public void addFirst(E e) { linkFirst(e); }
/** * Inserts the specified element at the end of this deque. * As the deque is unbounded, this method will never throw * {@link IllegalStateException}. * * <p>This method is equivalent to {@link #add}. * * @throws NullPointerException if the specified element is null */ public void addLast(E e) { linkLast(e); }
/** * Returns the predecessor of p, or the last node if p.prev has been * linked to self, which will only be true if traversing with a * stale pointer that is now off the list. */ final Node<E> pred(Node<E> p) { Node<E> q = p.prev; return (p == q) ? last() : q; }
/** * Returns the successor of p, or the first node if p.next has been * linked to self, which will only be true if traversing with a * stale pointer that is now off the list. */ final Node<E> succ(Node<E> p) { // TODO: should we skip deleted nodes here? Node<E> q = p.next; return (p == q) ? first() : q; }
public E element() { return getFirst(); } public void push(E e) { addFirst(e); }
/** * 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); }
/** * Returns {@code true} if this deque contains at least one * element {@code e} such that {@code o.equals(e)}. * * @param o element whose presence in this deque is to be tested * @return {@code true} if this deque contains the specified element */ public boolean contains(Object o) { if (o == null) return false; for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; if (item != null && o.equals(item)) return true; } return false; }
checkNotNull(e); Node<E> newNode = new Node<E>(e); if (beginningOfTheEnd == null) if (!casTail(t, last)) { casTail(t, last);