ConcurrentLinkedQueue源码阅读
来源:互联网 发布:网络征婚成功率 编辑:程序博客网 时间:2024/06/06 14:29
//非阻塞,一个基于链接节点的无界线程安全队列public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> implements Queue<E>, java.io.Serializable { private static final long serialVersionUID = 196745693267521676L; //头节点 private transient volatile Node<E> head; //尾结点 private transient volatile Node<E> tail; //链表节点 private static class Node<E> { volatile E item;//元素 volatile Node<E> next;//后继节点 Node(E item) { UNSAFE.putObject(this, itemOffset, item); } boolean casItem(E cmp, E val) { return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); } // 设置next域的值,并不会保证修改对其他线程立即可见 void lazySetNext(Node<E> val) { UNSAFE.putOrderedObject(this, nextOffset, val); } // 比较并替换next域的值 boolean casNext(Node<E> cmp, Node<E> val) { return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); } } /** * Tries to CAS head to p. If successful, repoint old head to itself * as sentinel for succ(), below. */ final void updateHead(Node<E> h, Node<E> p) { if (h != p && casHead(h, p)) h.lazySetNext(h);//h的next域指向它自己 } /** * Returns the successor of p, or the head node if p.next has been * linked to self, which will only be true if traversing with a * stale pointer that is now off the list. */ final Node<E> succ(Node<E> p) { Node<E> next = p.next; return (p == next) ? head : next; } /** * 如果tail节点的next节点不为空,则将入队节点设置成tail节点, * 如果tail节点的next节点为空,则将入队节点设置成tail的next节点, * 所以tail节点不总是尾节点. */ //在队列尾插入元素 public boolean offer(E e) { checkNotNull(e);//元素非null final Node<E> newNode = new Node<E>(e); for (Node<E> t = tail, p = t;;) { Node<E> q = p.next; if (q == null) {//p为尾结点 //p节点的next域指向newNode if (p.casNext(null, newNode)) { if (p != t) casTail(t, newNode); return true; } } else if (p == q) p = (t != (t = tail)) ? t : head; else // Check for tail updates after two hops. //p == t --> p = q 否则尾结点被其他线程修改 p = tail p = (p != t && t != (t = tail)) ? t : q; } } //获取队列头节点并删除 public E poll() { restartFromHead: for (;;) { for (Node<E> h = head, p = h, q;;) { E item = p.item; // item不为null并且比较并替换item成功 if (item != null && p.casItem(item, null)) { if (p != h)//表头发生变化,更新表头 updateHead(h, ((q = p.next) != null) ? q : p); return item; } // 表头的下一个节点为null,即链表只有一个“内容为null的表头节点”。则更新表头为p,并返回null else if ((q = p.next) == null) { updateHead(h, p); return null; } else if (p == q) continue restartFromHead; else p = q; } } } //从队列中移除指定元素 public boolean remove(Object o) { if (o == null) return false; Node<E> pred = null; // 获取第一个存活的结点 for (Node<E> p = first(); p != null; p = succ(p)) { E item = p.item; // 找到item相等的结点,并且将该结点的item设置为null if (item != null && o.equals(item) && p.casItem(item, null)) { Node<E> next = succ(p); if (pred != null && next != null) pred.casNext(p, next); return true; } pred = p; } return false; }}
0 0
- ConcurrentLinkedQueue源码阅读
- ConcurrentLinkedQueue源码分析整理
- ConcurrentLinkedQueue源码解析
- ConcurrentLinkedQueue源码分析
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- ConcurrentLinkedQueue
- conCurrentLinkedQueue
- JUC源码分析23-队列-ConcurrentLinkedQueue
- ConcurrentLinkedQueue的实现原理和源码分析
- 学习笔记之ConcurrentLinkedQueue源码分析整理
- 关于Python的自定义模块
- 关于python open函数缓冲区的问题
- 莫比乌斯究竟爱谁!
- 15、Java并发面试题
- SSH远程LINUX时Connection refused
- ConcurrentLinkedQueue源码阅读
- 如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter
- 关于博弈基础知识的总结:巴什博弈(Bash Game)、威佐夫博奕(Wythoff Game)、尼姆博奕(Nim Game)
- Android学习笔记之AndroidManifest.xml文件解析
- 数据结构—线性表(知识梳理)
- 搭建Grails框架(脚手架)——连接MongoDB数据库(IDEA)
- final-finally-finalize 区别
- [Android Pro] AIDL进程间传递自定义类型参数
- Tyvj 1041 表达式计算2