ConcurrentLinkedQueue源码阅读与理解
2018-01-05 11:13
302 查看
ConcurrentLinkedQueue源码阅读与理解
简述:该容器是无锁无边界的队列FIFO链表。
几个变量:
几个方法:
简述:该容器是无锁无边界的队列FIFO链表。
几个变量:
//记录头节点(不一定指向头,缓更新) private transient volatile Node<E> head; //记录尾节点(不一定指向尾,缓更新) private transient volatile Node<E> tail; //数据结构 private static class Node<E> { volatile E item; volatile Node<E> next; ...... }
几个方法:
//初始化构造方法 public ConcurrentLinkedQueue() { head = tail = new Node<E>(null); }; //入队add函数调用offer函数 public boolean add(E e) { return offer(e); }; //看看offer函数 public boolean offer(E e) { checkNotNull(e); //e==null? final Node<E> newNode = new Node<E>(e);//构造好节点 //插入的主体 for (Node<E> t = tail, p = t;;) { //将tail赋值给t、p变量 Node<E> q = p.next;//拿到tail的下一个节点变量 if (q == null) {//如果为空,则为正常插入 // p is last node 也就是p是最后一个节点 if (p.casNext(null, newNode)) { //CAS操作插入 if (p != t) // hop two nodes at a time 只有当插入两个的时候,具体是要被插入的元素跟tail不一致,tail才会被CAS操作改变 casTail(t, newNode); // Failure is OK. return true;//插入成功均返回true } // Lost CAS race to another thread; re-read next // CAS失败的线程则重头再来,这是多线程的情况 } else if (p == q) //如果P指向自己,只有在做出队列操作的时候,可能会出现这种情况,说明该节点是删除节点 p = (t != (t = tail)) ? t : head;//多线程:检查tail是否被更改了,如果没被更改就从头开始遍历插入 else //这个就是拿到下一个节点继续操作了,注意:t != (t=tail) 并不是原子操作,这里也是为了减少多线程插入的时间而做的判断 // Check for tail updates after two hops. p = (p != t && t != (t = tail)) ? t : q; } } //出队列poll函数 public E poll() { restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;;) { E item = p.item; if (item != null && p.casItem(item, null)) {//CAS直接设置为null,成功则出队成功 if (p != h) // 这里跟add类似,也是在删除两个的时候会出现这个情况,此时就更新头结点 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; } } } //注意:该容器队列长度size并不是强一致性的,而且,会迭代元素很慢,如果出现其他线程操作,会报错。所以,如果需要判断是否为空,最好用isEmpty函数: public boolean isEmpty() { return first() == null; }
相关文章推荐
- 《理解 ES6》阅读整理:函数(Functions)(四)Arrow Functions
- [Chrome源码阅读] 理解Chrome导航网址的流程及render进程启动模式
- [Chrome源码阅读] 理解Chrome的smart pointer
- 论文阅读理解 - Stacked Hourglass Networks for Human Pose Estimation
- 别人对CSAPP的阅读理解
- 开始阅读prototype1.5(参照9esuLuciano blog的注释和自己的理解)第一天
- 【bzoj1615】【Usaco2008 Mar】The Loathesome Hay Baler(阅读理解) 代码&题解
- VC目标代码的阅读理解2
- URAL 2002. Test Task (阅读理解)
- tensorflow cifar_10 代码阅读与理解
- 用Keras搞一个阅读理解机器人
- HashMap源码阅读与理解
- 深入理解Java虚拟机JVM高级特性与最佳实践阅读总结——第三章垃圾收集器与内存分配策略
- 对fork()函数的理解 分类: C/C++ 2015-07-29 14:20 4人阅读 评论(0) 收藏
- 如何阅读深入理解计算机系统
- Tensorflow做阅读理解与完形填空
- C语言文法阅读与理解序
- Structured Streaming Programming Guide官方文档再次阅读理解强化学习
- 阅读《C primer plus》 理解C中二维数组、数组指针
- 现在AI的阅读理解做的都比人类好了,它能用在那些方面呢?