
本教程 *** 作环境: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的一些概念和用法,对删除队列中的元素部分进行代码的展示,学会出队流程后,大家就可以运行这部分的实例了。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)