ConcurrentLinkedQueue出队

出队函数

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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值