//无参构造方法首尾分别指向item为null的哨兵节点 public ConcurrentLinkedQueue() { head = tail = new Node<E>(null); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//根据指定集合创建队列 public ConcurrentLinkedQueue(Collection<? extends E> c) { Node<E> h = null, t = null; for (E e : c) { checkNotNull(e);//判断元素是否为null Node<E> newNode = new Node<E>(e);//根据item创建Node· if (h == null) h = t = newNode;//首次插入设置首尾节点指向 else { t.lazySetNext(newNode);t的next指向新节点 t = newNode;//尾部节点指向新节点 } } //防止指定集合为空 if (h == null) h = t = new Node<E>(null); head = h; tail = t; }
public boolean offer(E e) { checkNotNull(e);//检测e是否为空 final Node<E> newNode = new Node<E>(e);//创建新节点 //从尾部开始插入 for (Node<E> t = tail, p = t;;) { Node<E> q = p.next; //判断q是否为空,如果是则说明p为尾节点 if (q == null) { // 尝试把p的next节点指向新节点 if (p.casNext(null, newNode)) {
if (p != t) // casTail(t, newNode); // 尝试将尾部节点设置为新节点,失败也没事也就说法其他线程已经设置了。 return true; } // Lost CAS race to another thread; re-read next } else if (p == q) //为了处理poll()方法导致的。。 p = (t != (t = tail)) ? t : head; else // 寻找尾部节点 p = (p != t && t != (t = tail)) ? t : q; } }
public E poll() { restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;;) { E item = p.item; //item不为空和尝试设置p节点值为null if (item != null && p.casItem(item, null)) { // Successful CAS is the linearization point // for item to be removed from this queue. if (p != h) // hop two nodes at a time updateHead(h, ((q = p.next) != null) ? q : p); return item; } //如果item为空或尝试设置失败就获得p的下一个节点,如果为空则说明队列为空 else if ((q = p.next) == null) { updateHead(h, p); return null; } //重新开始循环 else if (p == q) continue restartFromHead; //设置p为p的下一个节点 else p = q; } } }
public E peek() { restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;;) { E item = p.item; if (item != null || (q = p.next) == null) { updateHead(h, p); return item; } else if (p == q) continue restartFromHead; else p = q; } } }
获得头部节点不会弹出,执行该方法会将head节点指向第一个非空的节点
size()获得队列元素数量
1 2 3 4 5 6 7 8 9
public int size() { int count = 0; for (Node<E> p = first(); p != null; p = succ(p)) if (p.item != null) // Collection.size() spec says to max out if (++count == Integer.MAX_VALUE) break; return count; }