本教程 *** 作环境:windows7系统、java10版,DELL G3电脑。
1.出队说明
出队列的就是从队列里返回一个节点元素,并清空该节点对元素的引用。让我们通过每个节点出队的快照来观察下head节点的变化。
2.出队过程
首先获取头节点的元素,然后判断头节点元素是否为空,如果为空,表示另外一个线程已经进行了一次出队 *** 作将该节点的元素取走,如果不为空,则使用CAS的方式将头节点的引用设置成null,如果CAS成功,则直接返回头节点的元素,如果不成功,表示另外一个线程已经进行了一次出队 *** 作更新了head节点,导致元素发生了变化,需要重新获取头节点。
publicE poll() { Nodeh = 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 (Nodeh = 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条)