1、peek函数
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;
}
}
}
2、初始化队列
3、第1个线程
1)
for (Node<E> h = head, p = h, q;;) {
2)执行到这里时item为null
E item = p.item;
3)
if (item != null || (q = p.next) == null) {
4)
else
p = q;
第一轮循环结束
5)这时item等于李四
E item = p.item;
6)
updateHead(h, p);
点击进去可以看到‘
final void updateHead(Node<E> h, Node<E> p) {
if (h != p && casHead(h, p))
h.lazySetNext(h);
}
7)
casHead(h, p)
8)
h.lazySetNext(h);
void lazySetNext(Node<E> val) {
UNSAFE.putOrderedObject(this, nextOffset, val);
}
9)返回item=张三
4、第2个线程
1)
for (Node<E> h = head, p = h, q;;) {
2)item为李四
E item = p.item;
3)条件满足
if (item != null || (q = p.next) == null) {
4)
updateHead(h, p);
点击进去
final void updateHead(Node<E> h, Node<E> p) {
if (h != p && casHead(h, p))
h.lazySetNext(h);
}
条件不满足,返回。
5)返回李四
return item;
5、总结
逻辑是:指针定位到头节点,返回头节点的元素,更新下head指针,让head指向真正的头节点。后面的线程再过来时直接找到头节点,返回对应的item就ok了。