目录
7、iterator / descendingIterator
ConcurrentLinkedDeque表示一个无固定容量的,线程安全的,基于CAS而非ReentrantLock互斥锁实现的双端队列,其实现方式跟ConcurrentLinkedQueue类似,本篇博客就详细探讨该类的实现细节。
1、定义
ConcurrentLinkedDeque的类继承关系如下:
只实现了Deque接口,未实现BlockingDeque接口,相关方法的功能可以参考《Java8 LinkedBlockingDeque 源码解析》。
该类包含的实例属性如下:
//链表头
private transient volatile Node<E> head;
//链表尾
private transient volatile Node<E> tail;
private static final int HOPS = 2;
包含的静态属性通过static代码块初始化,如下:
其中PREV_TERMINATOR和NEXT_TERMINATOR都是两个静态常量,Node是一个静态的内部类,实现如下:
static final class Node<E> {
volatile Node<E> prev; //前一个节点
volatile E item; //关联的元素
volatile Node<E> next; //下一个节点
Node() { // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR
}
Node(E item) {
UNSAFE.putObject(this, itemOffset, item);
}
//compareAndSwapObject和putOrderedObject都会保证修改对其CPU立即可见
boolean casItem(E cmp, E val) {
return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
}
void lazySetNext(Node<E> val) {
UNSAFE.putOrderedObject(this, nextOffset, val);
}
boolean casNext(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
}
void lazySetPrev(Node<E> val) {
UNSAFE.putOrderedObject(this, prevOffset, val);
}
boolean casPrev(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
}
private static final sun.misc.Unsafe UNSAFE;
private static final long prevOffset;
private static final long itemOffset;
private static final long nextOffset;
//获取三个属性的偏移量
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> k = Node.class;
prevOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("prev"));
itemOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("item"));
nextOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("next"));
} catch (Exception e) {
throw new Error(e);
}
}
}
2、构造方法
public ConcurrentLinkedDeque() {
//初始化head和tail属性
head = tail = new Node<E>(null);
}
public ConcurrentLinkedDeque(Collection<? extends E> c) {
// Copy c into a private chain of Nodes
Node<E> h = null, t = null;
//遍历集合c
for (E e : c) {
checkNotNull(e);
Node<E> newNode = new Node<E>(e);
if (h == null)
h = t = newNode; //链表未初始化
else {
//插入到tail的后面
t.lazySetNext(newNode);
newNode.lazySetPrev(t);
t = newNode;
}
}
initHeadTail(h, t);
}
private void initHeadTail(Node<E> h, Node<E> t) {
if (h == t) {
if (h == null) //两个都是空
h = t = new Node<E>(null);
else {
//两个非空,即此时链表中只有一个元素,构建一个空节点作为tail
Node<E> newNode = new Node<E>(null);
t.lazySetNext(newNode);
newNode.lazySetPrev(t);
t = newNode;
}
}
head = h;
tail = t;
}
3、add / offer / addAll
add和offer类方法的核心就是linkFirst和linkLast方法。
public boolean add(E e) {
return offerLast(e);
}
public void addFirst(E e) {
linkFirst(e);
}
public void addLast(E e) {
linkLast(e);
}
public boolean offer(E e) {
return offerLast(e);
}
public boolean offerFirst(E e) {
linkFirst(e);
return true;
}
public boolean offerLast(E e) {
linkLast(e);
return true;
}
private void linkFirst(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
restartFromHead:
for (;;)
for (Node<E> h = head, p = h, q;;) {
if ((q = p.prev) != null && //head前面两个节点都非空
(q = (p = q).prev) != null)
//如果head节点发生变更,p等于新的head节点,否则p等于q,然后开始下一次for循环,直到有一个节点的prev为null,即找到链表最前面的一个节点
p = (h != (h = head)) ? h : q;
else if (p.next == p) // 这个节点原来是head,即将被移除,重新读取head
continue restartFromHead;
else {
//第一个的if条件不成立,p的prev为null,p就是链表中第一个节点
newNode.lazySetNext(p); // CAS piggyback
if (p.casPrev(null, newNode)) {
//如果cas修改prev成功
if (p != h) //如果p不等于head则修改head,当p等于head的前一个节点时p就不等于head
//如果等于则不修改,下一次调用此方法时再修改,相当于节省了一次casHead调用
//cas修改head,如果修改失败,则表示其他线程修改了head,其他线程插入节点只能插入到nowNode的后面,所以只要有一个线程修改成功即可
casHead(h, newNode);
return;
}
//如果修改失败,下一次for循环会重新读取p
}
}
}
private void linkLast(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
restartFromTail:
for (;;)
for (Node<E> t = tail, p = t, q;;) {
if ((q = p.next) != null && //如果tail后两个节点非空
(q = (p = q).next) != null)
//tail是否改变,如果变了p等于tail,否则等于q,继续下一次循环直到找到next为null的节点,即链表中最后一个节点
p = (t != (t = tail)) ? t : q;
else if (p.prev == p) //该节点原来是tail节点,即将被移除,重新读取tail
continue restartFromTail;
else {
// p is last node
newNode.lazySetPrev(p); // CAS piggyback
if (p.casNext(null, newNode)) {
//cas修改成功,newNode作为p的下一个节点
//同上,p等于t不修改tail,下一次调用时p不等于t则修改tail
if (p != t) // hop two nodes at a time
casTail(t, newNode); //只有一个线程修改成功即可,因为cas本身保证了链表的节点顺序
return;
}
//cas失败重新for循环找到链表最后一个节点
}
}
}
public boolean addAll(Collection<? extends E> c) {
if (c == this)
throw new IllegalArgumentException();
Node<E> beginningOfTheEnd = null, last = null;
//遍历集合c,将其中的元素转换成一个链表
for (E e : c) {
checkNotNull(e);
Node<E> newNode = new Node<E>(e);
if (beginningOfTheEnd == null)
beginningOfTheEnd = last = newNode;//初始化链表
else {
last.lazySetNext(newNode); //插入到链表的后面
newNode.lazySetPrev(last);
last = newNode;
}
}
if (beginningOfTheEnd == null) //链表为空
return false;
//将beginningOfTheEnd作为一个新节点原子的插入到链表后面,同上面的linkLast逻辑
restartFromTail:
for (;;)
for (Node<E> t = tail, p = t, q;;) { //如果tail后两个节点非空
if ((q = p.next) != null &&
(q = (p = q).next) != null)
p = (t != (t = tail)) ? t : q;
else if (p.prev == p) //p原来是tail节点,即将被移除
continue restartFromTail;
else {
//p是最后一个节点
beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
if (p.casNext(null, beginningOfTheEnd)) { //插入到p的后面成功
if (!casTail(t, last)) { //如果修改tail失败进入if分支,如果修改成功直接返回
//重新读取tail
t = tail;
if (last.next == null) //没有新的节点插入到last后面,再次尝试修改,如果有新的节点插入了,则插入新节点的线程会负责修改tail
casTail(t, last);
}
return true;
}
// Lost CAS race to another thread; re-read next
}
}
}
private boolean casHead(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
}
private boolean casTail(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
}
4、peek / poll / remove
public E peek() { return peekFirst(); }
public E peekFirst() {
//first返回链表的第一个节点,succ返回p的下一个有效节点
for (Node<E> p = first(); p != null; p = succ(p)) {
E item = p.item;
//插入链表中的节点item都是非null的,但是poll方法移除节点前会将item置为null然后再移除
if (item != null) //如果item为null则返回下一个有效节点
return item;
}
return null;
}
public E peekLast() {
//last返回链表的最后一个节点,pred返回p的前一个有效节点
for (Node<E> p = last(); p != null; p = pred(p)) {
E item = p.item;
if (item != null)
return item;
}
return null;
}
public E poll() { return pollFirst(); }
public E pollFirst() {
for (Node<E> p = first(); p != null; p = succ(p)) {
E item = p.item;
if (item != null && p.casItem(item, null)) {
//成功的将item修改为null,表示该节点即将从链表中移除
//unlink将目标节点从链表移除
unlink(p);
return item;
}
}
return null;
}
public E pollLast() {
for (Node<E> p = last(); p != null; p = pred(p)) {
E item = p.item;
if (item != null && p.casItem(item, null)) {
unlink(p);
return item;
}
}
return null;
}
public E remove() { return removeFirst(); }
public E removeFirst() {
return screenNullResult(pollFirst());
}
public E removeLast() {
return screenNullResult(pollLast());
}
public boolean remove(Object o) {
return removeFirstOccurrence(o);
}
public boolean removeFirstOccurrence(Object o) {
checkNotNull(o);
//从first开始往后遍历
for (Node<E> p = first(); p != null; p = succ(p)) {
E item = p.item;
if (item != null && o.equals(item) && p.casItem(item, null)) {
//找到目标节点,将item置为null并从链表中移除
unlink(p);
return true;
}
}
return false;
}
public boolean removeLastOccurrence(Object o) {
checkNotNull(o);
//从last往前遍历
for (Node<E> p = last(); p != null; p = pred(p)) {
E item = p.item;
if (item != null && o.equals(item) && p.casItem(item, null)) {
//找到目标节点,将item置为null并从链表中移除
unlink(p);
return true;
}
}
return false;
}
//返回链表中第一个节点
Node<E> first() {
restartFromHead:
for (;;)
for (Node<E> h = head, p = h, q;;) {
if ((q = p.prev) != null && //如果head的前2个节点非空
(q = (p = q).prev) != null)
//head变了,p等于新的head,否则等于q,重新循环直到找到prev为null的节点
p = (h != (h = head)) ? h : q;
else if (p == h //如果p等于head 或者p不等于head,将p修改成head成功,返回p
|| casHead(h, p))
return p;
else
//casHead失败,有其他线程修改了head,for循环重新读取head
continue restartFromHead;
}
}
final Node<E> succ(Node<E> p) {
//如果p等于q,p原来是head节点即将被移除,重新获取head节点,否则就是下一个节点
Node<E> q = p.next;
return (p == q) ? first() : q;
}
Node<E> last() {
restartFromTail:
for (;;)
//逻辑跟first基本相同
for (Node<E> t = tail, p = t, q;;) {
if ((q = p.next) != null && //如果tail的后2个节点非空
(q = (p = q).next) != null)
p = (t != (t = tail)) ? t : q;
else if (p == t //如果p等于tail则返回
|| casTail(t, p))
return p;
else
//casTail失败,重新读取tail
continue restartFromTail;
}
}
final Node<E> pred(Node<E> p) {
Node<E> q = p.prev;
//p等于q说明p即将被移除,重新读取tail,否则返回前一个节点
return (p == q) ? last() : q;
}
//如果为空抛出异常
private E screenNullResult(E v) {
if (v == null)
throw new NoSuchElementException();
return v;
}
5、unlinkFirst / unlinkLast
这两个分别用于移除链表头和链表尾节点,如果链表头的下一个节点,链表尾的上一个节点的item都不为null,则直接返回,并不会直接移除。如果item为null且存在其他节点时,才会真正的移除,并重置head和tail节点。
private void unlinkFirst(Node<E> first, Node<E> next) {
// assert first != null;
// assert next != null;
// assert first.item == null;
for (Node<E> o = null, p = next, q;;) {
if (p.item != null //p节点是一个有效节点
|| (q = p.next) == null) { //p是最后一个节点
//o在第一遍循环时为null,不会进入此if分支
//next节点的item为null,即该节点也是需要被移除的,next节点后还有其他节点时就会进入else分支,再次for循环如果p.item不为null
//或者p是最后一个节点就会进入下面的if分支
if (o != null && p.prev != p && first.casNext(next, p)) {
//casNext修改成功会将first到p之间的item为null的多个节点都从链表中移除了,此时只是first的next属性修改了,但是p的prev属性未修改
//skipDeletedPredecessors就是修改p的prev属性,将前面的item为null的需要被移除的节点都跳过
skipDeletedPredecessors(p);
if (first.prev == null && //first还是head节点
(p.next == null || p.item != null) && //p是最后一个节点或者p是一个有效节点
p.prev == first) { //p的prev属性指向first
//调整head和tail节点
updateHead(); // Ensure o is not reachable from head
updateTail(); // Ensure o is not reachable from tail
//将o从链表中移除
o.lazySetNext(o);
o.lazySetPrev(prevTerminator());
}
}
//第一遍for循环进入此if分支后就直接返回了,即没有实际的移除节点
return;
}
//p.item为null,q不为null时进入下面的分支,即可能存在多个item为null的节点
else if (p == q) //p本身即将被移除,p移除了,p的前面的多个节点因为链表关系被破坏了也会移除
return;
else {
//p等于q,继续遍历下一个节点
o = p;
p = q;
}
}
}
private void unlinkLast(Node<E> last, Node<E> prev) {
// assert last != null;
// assert prev != null;
// assert last.item == null;
for (Node<E> o = null, p = prev, q;;) {
if (p.item != null || (q = p.prev) == null) {
//第一遍for循环进入if分支时,o为null,直接return了,即没有实际移除节点
//进入最下面的else分支后,找到了一个有效节点或者遍历到链表的第一个节点,此时已跳过多个item为null的节点
if (o != null && p.next != p && last.casPrev(prev, p)) {
//将p作为last的prev属性,skipDeletedSuccessors会修改p的next属性,让其指向last
skipDeletedSuccessors(p);
//last和p的属性都调整后,last和p之间的item为null的节点就从链表中移除了
if (last.next == null &&
(p.prev == null || p.item != null) &&
p.next == last) {
//调整head和tail
updateHead(); // Ensure o is not reachable from head
updateTail(); // Ensure o is not reachable from tail
//将o从链表中移除
o.lazySetPrev(o);
o.lazySetNext(nextTerminator());
}
}
return;
}
//p的item为null且p还有前一个节点,说明有多个为null的节点
else if (p == q) //p已经从链表移除
return;
else {
//继续遍历前面的一个节点,直到找到一个有效节点或者遍历到链表的第一个节点
o = p;
p = q;
}
}
}
private void skipDeletedPredecessors(Node<E> x) {
whileActive:
do {
Node<E> prev = x.prev;
// assert prev != null;
// assert x != NEXT_TERMINATOR;
// assert x != PREV_TERMINATOR;
Node<E> p = prev;
findActive:
for (;;) {
//正常情况x的前一个节点的item为null,如果不为null,说明该节点是有效节点,则终止内层的for循环
//将该节点设置为x的prev节点
if (p.item != null)
break findActive;
//p.item为null
Node<E> q = p.prev;
if (q == null) { //p是链表第一个节点
if (p.next == p) //p即将被移除,内存for循环终止,继续外层do/while循环,处理prev的前一个节点
continue whileActive;
break findActive; //p是一个有效节点,终止内层的for循环
}
else if (p == q) //该节点也是无效的,内存for循环终止,继续外层do/while循环,处理prev的前一个节点
continue whileActive;
else
//p不等于q,p前面还有其他节点,则继续for循环遍历其他节点
p = q;
}
//如果p不等于prev则将x的prev属性设置为p
if (prev == p || x.casPrev(prev, p))
return;
//x.item不为null,说明x是一个有效节点,x的next为null说明x是链表最后一个节点,这两条件都不满足则终止循环
//满足这两条件时需要正确的设置prev属性,否则可以忽略
} while (x.item != null || x.next == null);
}
private void skipDeletedSuccessors(Node<E> x) {
whileActive:
do {
Node<E> next = x.next;
// assert next != null;
// assert x != NEXT_TERMINATOR;
// assert x != PREV_TERMINATOR;
Node<E> p = next;
findActive:
for (;;) {
//找到一个有效节点,则终止内层的for循环,将该节点设置为x的next节点
if (p.item != null)
break findActive;
//p的item为null
Node<E> q = p.next;
if (q == null) { //p是链表最后一个节点了
if (p.prev == p) //p即将被移除,内存for循环终止,继续外层do/while循环,处理next的下一个节点
continue whileActive;
break findActive; //终止内层的for循环
}
else if (p == q) //p即将被移除,内存for循环终止,继续外层do/while循环,处理next的下一个节点
continue whileActive;
else
p = q; //继续处理下一个节点
}
//如果next不等于p,将p作为x的next节点
if (next == p || x.casNext(next, p))
return;
//x.item不为null,说明x是一个有效节点,x的prev为null说明x是链表第一个节点,这两条件都不满足则终止循环
} while (x.item != null || x.prev == null);
}
//从head节点往前遍历找到链表的第一个节点,将其置为head
private final void updateHead() {
Node<E> h, p, q;
restartFromHead:
while ((h = head).item == null //head的item为null说明head需要被移除
&& (p = h.prev) != null) { //head的前一个节点不为null,说明head可以被前面的节点替换
for (;;) {
if ((q = p.prev) == null || //如果p就是链表的第一个节点
(q = (p = q).prev) == null) { //如果q是链表的第一个节点,此时p等于q
//将head修改为p,p是链表的第一个节点
if (casHead(h, p))
return;
else
//修改head失败,终止内层for循环,继续外层while循环,重新读取head
continue restartFromHead;
}
else if (h != head) //如果head变了,重新读取head
continue restartFromHead;
else
p = q; //遍历前一个节点
}
}
}
//从tail节点往后遍历找到链表最后一个节点,将其置为tail
private final void updateTail() {
// Either tail already points to an active node, or we keep
// trying to cas it to the last node until it does.
Node<E> t, p, q;
restartFromTail:
//tail的item为null需要被移除,且存在下一个节点
while ((t = tail).item == null && (p = t.next) != null) {
for (;;) {
if ((q = p.next) == null ||
(q = (p = q).next) == null) {
//找到了链表最后一个几点,将tail修改为p
if (casTail(t, p))
return;
else
//修改失败,重新读取p
continue restartFromTail;
}
else if (t != tail)
continue restartFromTail; //tail变了,重新读取p
else
p = q; //遍历下一个节点
}
}
}
@SuppressWarnings("unchecked")
Node<E> prevTerminator() {
return (Node<E>) PREV_TERMINATOR;
}
@SuppressWarnings("unchecked")
Node<E> nextTerminator() {
return (Node<E>) NEXT_TERMINATOR;
}
6、unlink
unlink方法用于从链表中移除某个节点,该节点可以是链表头或者链表尾或者是链表中间的某个节点。unlink方法不是每次都将节点从链表中完全移除的,而是有延迟,一次移除时可能会将多个item为null的节点从链表中移除。注意item为null表示这个节点需要被移除,prev或者next属性指向自己,表明这个节点周围的多个节点可能都被移除了,不需要再遍历该节点的前后节点了,而是重新从head或者tail节点遍历。
void unlink(Node<E> x) {
// assert x != null;
// assert x.item == null;
// assert x != PREV_TERMINATOR;
// assert x != NEXT_TERMINATOR;
final Node<E> prev = x.prev;
final Node<E> next = x.next;
if (prev == null) {
//x是链表头节点
unlinkFirst(x, next);
} else if (next == null) {
//x是链表尾节点
unlinkLast(x, prev);
} else {
//移除链表中间的某个节点
Node<E> activePred, activeSucc;
boolean isFirst, isLast;
int hops = 1;
//往前遍历找到第一个有效的节点
for (Node<E> p = prev; ; ++hops) {
if (p.item != null) { //找到一个有效节点,终止循环
activePred = p;
isFirst = false;
break;
}
//p.item为null
Node<E> q = p.prev;
if (q == null) { //p是链表第一个节点
if (p.next == p) //p是无效节点,p周围的节点可能都会被移除,再遍历无意义,下一次unlink时会删除该节点
return;
activePred = p;
isFirst = true;
break;
}
else if (p == q) //p是无效节点
return;
else
p = q; //继续遍历前一个节点
}
//往后遍历找到第一个有效的节点
for (Node<E> p = next; ; ++hops) {
if (p.item != null) { //找到一个有效节点,终止循环
activeSucc = p;
isLast = false;
break;
}
Node<E> q = p.next;
if (q == null) { //p是链表最后一个节点
if (p.prev == p) //p是无效节点,p周围的节点可能都会被移除,再遍历无意义
return;
activeSucc = p;
isLast = true;
break;
}
else if (p == q) //p是无效节点
return;
else
p = q; //继续遍历下一个节点
}
// HOPS等于2,如果上面两个for循环都只循环了一次就找到了有效节点
if (hops < HOPS
// always squeeze out interior deleted nodes
&& (isFirst | isLast)) //如果x是链表第二个节点或者顺数第二个节点
return;
//调整activePred的next属性,将activePred到next节点之间的节点从链表中移除
skipDeletedSuccessors(activePred);
//调整activeSucc的prev属性
skipDeletedPredecessors(activeSucc);
// Try to gc-unlink, if possible
if ((isFirst | isLast) &&
(activePred.next == activeSucc) && //activePred和activeSucc连在一起了,中间的x就被移除了
(activeSucc.prev == activePred) &&
(isFirst ? activePred.prev == null : activePred.item != null) && //x是链表头第二个节点,如果不是item不为null
(isLast ? activeSucc.next == null : activeSucc.item != null)) { //x是链表倒数第二个节点,如果不是item不为null
//更新链表头和链表尾
updateHead(); // Ensure x is not reachable from head
updateTail(); // Ensure x is not reachable from tail
//重置x的prev和next属性,将其从链表中移除
x.lazySetPrev(isFirst ? prevTerminator() : x);
x.lazySetNext(isLast ? nextTerminator() : x);
}
}//else结束
}
7、iterator / descendingIterator
public Iterator<E> iterator() {
return new Itr();
}
public Iterator<E> descendingIterator() {
return new DescendingItr();
}
Itr和DescendingItr都是内部类,继承自另一个内部类AbstractItr,这两个的定义如下:
AbstractItr的实现如下:
private abstract class AbstractItr implements Iterator<E> {
//下一次next方法返回的节点
private Node<E> nextNode;
//下一次next方法返回的元素
private E nextItem;
//上一次next方法返回的节点
private Node<E> lastRet;
abstract Node<E> startNode();
abstract Node<E> nextNode(Node<E> p);
AbstractItr() {
advance();
}
private void advance() {
lastRet = nextNode;
//构造方法调用时nextNode为null
Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
//nextNode是下一次for循环时调用的
for (;; p = nextNode(p)) {
if (p == null) {
//链表为空或者无有效节点
nextNode = null;
nextItem = null;
break;
}
E item = p.item;
if (item != null) { //nextNode和nextItem赋值
nextNode = p;
nextItem = item;
break;
}
//item为null则调用nextNode获取下一个节点
}
}
public boolean hasNext() {
return nextItem != null;
}
public E next() {
E item = nextItem;
if (item == null) throw new NoSuchElementException();
advance();
return item;
}
public void remove() {
Node<E> l = lastRet;
if (l == null) throw new IllegalStateException();
l.item = null; //item置为null
unlink(l); //从链表中移除
lastRet = null;
}
}