Java 线程 ? ConcurrentLinkedQueue
作者:lacker 发布时间:[ 2016/11/17 11:43:15 ] 推荐标签:Java 线程
为什么会出现p == q
假设下面这种情况:
在第一种情况下,线程A执行offer操作:
1、第一次循环的时候
2、tail = node0, p = t = node0
3、执行 Node<E> q = p.next; 之后q = p.next,也是node0.next
4、执行 if (q == null),不满足,继续往下
到了 else if (p == q) 这一步的时候线程A暂停
线程A现在的结果是:
head = node0
tail = node0
t = node0
p = node0
q = node0.next
因为程序时多线程的,我们假设线程A暂定在了第4步,接下来看线程B,线程B执行poll操作:
第一次循环:
· head = node0, p = h = node0;
· 执行 E item = p.item;,item = null
· if (item != null && p.casItem(item, null)) 不满足
· 执行 else if ((q = p.next) == null),q = node1,条件不满足
· 执行 else if (p == q),条件不满足
· 执行 p = q;,p = node1
第二次循环:
· head = node0, h = node0, p = node1;
· 执行 E item = p.item;,item = node2
· if (item != null && p.casItem(item, null)), item != null 满足,如果CAS操作成功
p != h 成立,调用updateHead
执行 updateHead(h, ((q = p.next) != null) ? q : p); 之后,q = node2
在updateHead里面
h != p 成立,如果CAS操作成功(将head设置为node2)
执行 h.lazySetNext(h);,这个时候 h = node0,这个方法执行完之后,node0.next = node0
· 将item返回
这个时候队列是图中第二种情况,线程A结果为:
head = node2
tail = node0
t = node0
p = node0
q = node0.next = node0
看到结果了吧,这个时候 p = q = node0 !其实主要原因是在 updateHead方法的 h.lazySetNext(h) 操作里面,将旧的head.next设置成为了自己即 head.next = head。但是要注意:是旧的head
从上面分析的过程要注意:
1、多线程执行环境,单线程下一定不会出现这种情况
2、注意引用赋值比如 Node<E> q = p.next,q指向的是p.next,虽然目前 p.next = node1,但是当p.next指向变了之后,q也跟着变了
3、再是阅读源码的时候一定要弄清楚调用的每个方法的作用,这样才能对整个方法有一个准确的理解,比如这里的 h.lazySetNext(h);
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11