ConcurrentLinkedQueue在java出队分析

ConcurrentLinkedQueue在java出队分析,第1张

ConcurrentLinkedQueue在java出队分析

本教程 *** 作环境:windows7系统、java10版,DELL G3电脑。

1.出队说明

出队列的就是从队列里返回一个节点元素,并清空该节点对元素的引用。让我们通过每个节点出队的快照来观察下head节点的变化。

2.出队过程

首先获取头节点的元素,然后判断头节点元素是否为空,如果为空,表示另外一个线程已经进行了一次出队 *** 作将该节点的元素取走,如果不为空,则使用CAS的方式将头节点的引用设置成null,如果CAS成功,则直接返回头节点的元素,如果不成功,表示另外一个线程已经进行了一次出队 *** 作更新了head节点,导致元素发生了变化,需要重新获取头节点。

publicE poll() { 
Node h = head; 
// p表示头节点,需要出队的节点06
Node p = h; 
for(inthops = 0;; hops++) { 
// 获取p节点的元素 
E item = p.getItem(); 
// 如果p节点的元素不为空,使用CAS设置p节点引用的元素为null,如果成功则返回p节点的元素。 
if(item != null&& p.casItem(item, null)) { 
if(hops >= HOPS) { 
//将p节点下一个节点设置成head节点 
Node q = p.getNext(); 
updateHead(h, (q != null) ? q : p); 
} 
returnitem; 
} 
// 如果头节点的元素为空或头节点发生了变化,这说明头节点已经被另外一个线程修改了。那么获取p节点的下一个节点 
Node next = succ(p); 
// 如果p的下一个节点也为空,说明这个队列已经空了 
if(next == null) { 
// 更新头节点。 
updateHead(h, p); 
break; 
} 
// 如果下一个元素不为空,则将头节点的下一个节点设置成头节点50
p = next; 
} 
returnnull; 
}

3.出队实例

poll方法

public E poll() {
    restartFromHead:
    for (; ; ) {
        for (Node h = head, p = h, q; ; ) {
            E item = p.item;
 
            if (item != null && p.casItem(item, null)) {    // CASE2: 队首是非哨兵结点(item!=null)
                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) {      // CASE1: 队首是一个哨兵结点(item==null)
                updateHead(h, p);
                return null;
            } else if (p == q)
                continue restartFromHead;
            else
                p = q;
        }
    }
}

以上就是ConcurrentlinkedQueue在java出队分析,根据ConcurrentlinkedQueue的一些概念和用法,对删除队列中的元素部分进行代码的展示,学会出队流程后,大家就可以运行这部分的实例了。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/3017568.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-28
下一篇 2022-09-28

发表评论

登录后才能评论

评论列表(0条)

保存