标签:order 并发 declared 内容 内存 boolean 作用 发包 检查
CAS(Compare And Swap)
简单的来说,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则返回V
CAS指令在Intel CPU上称为CMPXCHG指令,它的作用是将指定内存地址的内容与所给的某个值相比,如果相等,则将其内容替换为指令中提供的新值,如果不相等,则更新失败。这一比较并交换的操作是原子的,不可以被中断。CAS是通过硬件命令保证了原子性。
从内存领域来说这是乐观锁,因为它在对共享变量更新之前会先比较当前值是否与更新前的值一致,如果是,则更新,如果不是,则无限循环执行(称为自旋),直到当前值与更新前的值一致为止,才执行更新。
首先声明了一个volatile变量value,我们知道volatile保证了变量的内存可见性,也就是所有工作线程中同一时刻都可以得到一致的值。
// setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); //Unsage类的方法,大部分是对内存的直接操作,所以不安全 private static final long valueOffset;// 注意是静态的 static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value"));// 反射出value属性,获取其在内存中的位置 } catch (Exception ex) { throw new Error(ex); } } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
在Java并发包中有一些并发框架也使用了自旋CAS的方式来实现原子操作,比如LinkedTransferQueue类的Xfer方法。CAS虽然很高效的解决原子操作,但是CAS仍然存在三大问题。ABA问题,循环时间长开销大和只能保证一个共享变量的原子操作。
从Java1.5开始JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。
public boolean compareAndSet( V expectedReference, //预期引用 V newReference, //更新后的引用 int expectedStamp, //预期标志 int newStamp //更新后的标志 )
标签:order 并发 declared 内容 内存 boolean 作用 发包 检查
原文地址:http://www.cnblogs.com/jerrice/p/7298451.html