/** * Returns the first live (non-deleted) node on list, or null if none. * This is yet another variant of poll/peek; here returning the * first node, not element. We could make peek() a wrapper around * first(), but that would cost an extra volatile read of item, * and the need to add a retry loop to deal with the possibility * of losing a race to a concurrent poll(). */ Node<E> first() { restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;; p = q) { booleanhasItem= (p.item != null); if (hasItem || (q = p.next) == null) { updateHead(h, p); return hasItem ? p : null; } elseif (p == q) continue restartFromHead; } } }
/** * Returns {@code true} if this queue contains no elements. * * @return {@code true} if this queue contains no elements */ publicbooleanisEmpty() { return first() == null; }
/** * Returns the number of elements in this queue. If this queue * contains more than {@code Integer.MAX_VALUE} elements, returns * {@code Integer.MAX_VALUE}. * * <p>Beware that, unlike in most collections, this method is * <em>NOT</em> a constant-time operation. Because of the * asynchronous nature of these queues, determining the current * number of elements requires an O(n) traversal. * Additionally, if elements are added or removed during execution * of this method, the returned result may be inaccurate. Thus, * this method is typically not very useful in concurrent * applications. * * @return the number of elements in this queue */ publicintsize() { restartFromHead: for (;;) { intcount=0; for (ConcurrentLinkedQueue.Node<E> p = first(); p != null;) { if (p.item != null) if (++count == Integer.MAX_VALUE) break; // @see Collection.size() if (p == (p = p.next)) continue restartFromHead; } return count; } }