赞
踩
在进行CAS操作数据时,会检查原始数据是否被发生改变,如果没有发生改变,则更新数据为期望值,但是如果原始数据是A、期望值是B,数据又被更新成A,这时候,CAS操作就无法确定数据是否被发生了变化,其实,要被更改的数据已经发生变化,由A->B->A。
解决ABA问题的思路是对更改数据操作增加版本号,每次对数据操作时,在操作的数据前增加版本号,自动加一,比如。A->B->A,加上版本号:1A->2B->3A。在JDK1.5后,Atomic包里增加了一个类AtomicStampedReference来解决ABA问题,这个类里的compareAndSet方法会首先检查当前数据的引用是否和预期的引用相等,并且会检查当前的标识和预期标识是否相等,如果两个条件同时成立,则完成CAS操作,当前数据的引用会被更改为预期引用,当前的标识会被更新成预期标识。
自旋的CAS如果长时间不成功,就会导致CPU执行开销变大。
当对多个共享变量进行操作时,就无法保证原子操作。可以使用多个变量合并成一个变量来结局。比如 i=A,j=1,合并成一个变量就是ij=A1,这样就可以对这个合并后的变量进行原子操作。jdk1.5提供了AtomicReference类来保证引用对象之间的原子性,可以把多个变量放在一个对象中进行CAS操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。