我阅读JDK ConcurrentLinkedQueue时,发现UNSAFE.compareAndSwapObject非常奇怪。(class CLQ是从ConcurrentLinkedQueue复制过来的,以便于调试...) 当我将第一个项目提供给ConcurrentLinkedQueue时。
在执行
p.casNext(null, newNode)
之前,head==tail==p==t引用相同的对象,如下所示。进入casNext后
UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
p.next正如预期一样引用newNode,如下所示。
退出offer
一切变得奇怪...我可以理解为什么p.next引用会改变为p,以及为什么head引用newNode自动...
代码:ConcurrentLinkedQueue.class offer()
public boolean offer(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t;;) {
Node<E> q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
// Successful CAS is the linearization point
// for e to become an element of this queue,
// and for newNode to become "live".
if (p != t) // hop two nodes at a time
casTail(t, newNode); // Failure is OK.
return true;
}
// Lost CAS race to another thread; re-read next
}
else if (p == q)
// We have fallen off list. If tail is unchanged, it
// will also be off-list, in which case we need to
// jump to head, from which all live nodes are always
// reachable. Else the new tail is a better bet.
p = (t != (t = tail)) ? t : head;
else
// Check for tail updates after two hops.
p = (p != t && t != (t = tail)) ? t : q;
}
}
null
)进行比较,并在比较成功时设置为指定的第二个参数(这里是newNode
)。特别之处在于它是以原子方式执行的。有一个公共 API 为应用程序提供相同的功能。 - Holger