1.先理解一下ABA问题,(这篇文章解释了什么是ABA问题,也说了两种解决方案,但是第二种明显是逃避线程同步)

http://wen866595.iteye.com/blog/1672775

2.可是为什么ABA会让CAS混乱呢,我还是没有理解,以为我认为A变B,再变A,那样不是相当于没变吗?那操作不是可以照旧吗?但是这里的AB不是数字,而是对象,地址。

下面这个文章就说明了这个道理:

http://www.360doc.com/content/14/0811/10/1073512_400983810.shtml 中:

  ABA问题最容易发生在lock free 的算法中的,CAS首当其冲,因为CAS判断的是指针的地址。如果这个地址被重用了呢,问题就很大了。(地址被重用是很经常发生的,一个内存分配后释放了,再分配,很有可能还是原来的地址)

我还有一点疑问,就是上面这个说的,在哪种情况下能发生,我想不出例子来!

3.解决:

如果在算法中采用自己的方式来管理节点对象的内存,那么可能出现ABA问题。在这种情况下,即使链表的头结点仍然只想之前观察到的节点,那么也不足 以说明链表的内容没有发生变化。如果通过垃圾回收器来管理链表节点仍然无法避免ABA问题,那么还有一个相对简单的解决方法:不是只是更新某个引用的值, 而是更新两个值,包含一个引用和一个版本号。即使这个值由A变成B,然后又变为A,版本号也将是不同的。AtomicStampedReference以 及AtomicMarkableReference支持在两个变量上执行原子的条件更新。AtomicStampedReference将更新一个“对象 —-引用”二元组,通过在引用上加上“版本号”,从而避免ABA问题。类似地,AtomicMarkableReference将更新一个“对象引用—- 布尔值”二元组,在某些算法中将通过这种二元组使节点保存在链表中同时又将其标记为“已删除节点”。

 

下面这里是AtomicStampedReference的使用方法,里面对ABA让CAS混乱的原因也说明的非常好,CAS的算法,本身是有缺陷的。

http://hustpawpaw.blog.163.com/blog/static/184228324201210811243127/

虽然有了AtomicStampedReference的使用方法,但是没有解决原作者自己提到的混乱问题,所以还在找AtomicStampedReference的使用。