ConcurrentLinkedQueue的peek

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了。

发布了104 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zjuwzp/article/details/103829500
今日推荐