1、简介
1.1 介绍
基于链接节点的无界并发deque 。 并发插入,删除和访问操作可以跨多个线程安全执行。 A ConcurrentLinkedDeque是许多线程将共享对公共集合的访问的适当选择。 像大多数其他并发集合实现一样,此类不允许使用null元素。 这是一个双向链表 size方法不是一个准确的操作
1.2 构造
ConcurrentLinkedDeque()
ConcurrentLinkedDeque(Collection<? extends E> c)
1.3 继承
java
.lang.Object
java
.util.AbstractCollection<E>
java
.util.concurrent.ConcurrentLinkedDeque<E>
1.4 主要方法
boolean
add(E e)
boolean
addAll(Collection<? extends E> c)
void
addFirst(E e)
void
addLast(E e)
void
clear()
boolean
contains(Object o)
E
element()
E
getFirst()
E
getLast()
boolean
offer(E e)
boolean
offerFirst(E e)
boolean
offerLast(E e)
E
peek()
E
peekFirst()
E
peekLast()
E
poll()
E
pollFirst()
E
pollLast()
E
pop()
void
push(E e)
E
remove()
boolean
remove(Object o)
E
removeFirst()
boolean
removeFirstOccurrence(Object o)
E
removeLast()
boolean
removeLastOccurrence(Object o)
2、源代码
public class ConcurrentLinkedDeque<E>
extends AbstractCollection<E>
implements Deque<E>, java.io.Serializable {
private transient volatile Node<E> head;
private transient volatile Node<E> tail;
static final class Node<E> {
volatile Node<E> prev;
volatile E item;
volatile Node<E> next;
Node() {
}
Node(E item) {
UNSAFE.putObject(
this, itemOffset, item);
}
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);
}
}
}
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 &&
(q = (p = q).prev) !=
null)
p = (h != (h = head)) ? h : q;
else if (p.next == p)
continue restartFromHead;
else {
newNode.lazySetNext(p);
if (p.casPrev(
null, newNode)) {
if (p != h)
casHead(h, newNode);
return;
}
}
}
}
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 &&
(q = (p = q).next) !=
null)
p = (t != (t = tail)) ? t : q;
else if (p.prev == p)
continue restartFromTail;
else {
newNode.lazySetPrev(p);
if (p.casNext(
null, newNode)) {
if (p != t)
casTail(t, newNode);
return;
}
}
}
}
}