出队函数
public E poll() {
restartFromHead:
for (;;) {
for (Node<E> h = head, p = h, q;;) {
E item = p.item;
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;
}
else if ((q = p.next) == null) {
updateHead(h, p);
return null;
}
else if (p == q)
continue restartFromHead;
else
p = q;
}
}
}
1)初始化队列
2)循环条件初始化
for (Node<E> h = head, p = h, q;;) {
3)这时的item肯定为null
E item = p.item;
4)这里的条件肯定不满足
else if ((q = p.next) == null) {
5)
else
p = q;
6)开始第二轮循环
7)这时的item为张三
E item = p.item;
8)将队列的头部节点(哨兵的下一个节点)的item值设为null,这是CAS操作,保证同一时间就一个线程可以成功。
p.casItem(item, null)
9)
((q = p.next) != null) ? q : p
10)按上面的分析,这里传进去的是h和q这两个指针
updateHead(h, ((q = p.next) != null) ? q : p);
11)
final void updateHead(Node<E> h, Node<E> p) {
if (h != p && casHead(h, p))
h.lazySetNext(h);
}
void lazySetNext(Node<E> val) {
UNSAFE.putOrderedObject(this, nextOffset, val);
}
这个函数的作用是将原哨兵节点的next指针指向了自己,后续会被垃圾回收
12)这里会返回张三
return item;