淘宝清英在此文对ConcurrentLinkedQueue做了详细分析

http://www.infoq.com/cn/articles/ConcurrentLinkedQueue

cas实现没有涉及,我又读了一下ConcurrentLinkedQueue.Node类,记录此文作为补充

该类cas相关的入队的代码在285行:

} else if (p.casNext(null, n)) {

查看casNext详细:

ConcurrentLinkedQueue.Node:

       boolean casNext(Node<E> cmp, Node<E> val) {

           return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);

       }

       private static final sun.misc.Unsafe UNSAFE =sun.misc.Unsafe.getUnsafe();

       private static final long nextOffset =objectFieldOffset(UNSAFE, "next", Node.class);

反编译 sun.misc.Unsafe,可以看到:

public final native boolean compareAndSwapObject(Object paramObject1, long paramLong, Object paramObject2, Object paramObject3);

结合CAS算法:

cas需要三个参数,读写位置v,比较值a,写入值b;仅当v的值等于a才写入b

可以猜测 compareAndSwapObject方法的第二、三、四参数分别对应v a b

该类cas的实现是通过jni实现的

--------------------------------------------------------

最后Node类的注释中提到了:

this implementation relies on the fact that in garbage collected systems, there is no possibility of ABA problems due  to recycled nodes。

翻译过来应该是:这个实现(cas)依赖于gc系统,不会出现因为可重用节点导致的ABA问题。

这要提一下ABA问题:如果系统节点可重用,v的值由线程T2改为B,再由线程T3改为A,那么线程T1会发生误判,认为v的值没有变动。(这里的值指的应该是内存地址,两个equals相等的A认为是不同的)

node的注释是说T1会一直持有A,所以A不会被回收,也不能重用,自然不会发生其他线程设置v的值与A相同(地址相同)的现象。