您的位置:首页 > 产品设计 > UI/UE

ConcurrentLinkedQueue cas实现分析

2013-08-28 11:34 218 查看
淘宝清英在此文对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相同(地址相同)的现象。

本文出自 “Ying:好记性不如烂笔头” 博客,请务必保留此出处http://yingtju.blog.51cto.com/3760152/1284270
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: