一、CAS(Compare And Swap)
顾名思义,CAS就是比较与交换。具体解释如下:
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。CAS 有效地说明了 “ 我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”
二、java.ut l.concurrent.atomic
【标量类】:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
【数组类】:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
【更新器类】:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
【复合变量类】:AtomicMarkableReference,AtomicStampedReference
就拿第一组来说,均采用了CAS方式。
三、源码解读
以AtomicInteger为例,源码如下:
private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile int value; ...... /** * Atomically sets to the given value and returns the old value. * * @param newValue the new value * @return the previous value */ public final int getAndSet(int newValue) { for (;;) { int current = get(); if (compareAndSet(current, newValue)) return current; } } /** * Atomically sets the value to the given updated value * if the current value {@code ==} the expected value. * * @param expect the expected value * @param update the new value * @return true if successful. False return indicates that * the actual value was not equal to the expected value. */ public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
从上述代码可以看到,AtomicInteger获取value值是通过Unsafe类的objectFieldOffset()方法,然后调用Unsafe类的compareAndSwapInt()方法完成CAS操作。下面看看Unsafe这几个方法,如下:
objectFieldOffset():
/*** * Returns the memory address offset of the given static field. * The offset is merely used as a means to access a particular field * in the other methods of this class. The value is unique to the given * field and the same value should be returned on each subsequent call. * 返回指定静态field的内存地址偏移量,在这个类的其他方法中这个值只是被用作一个访问 * 特定field的一个方式。这个值对于 给定的field是唯一的,并且后续对该方法的调用都应该 * 返回相同的值。 * * @param field the field whose offset should be returned. * 需要返回偏移量的field * @return the offset of the given field. * 指定field的偏移量 */ public native long objectFieldOffset(Field field);
compareAndSwapInt():
/*** * Compares the value of the integer field at the specified offset * in the supplied object with the given expected value, and updates * it if they match. The operation of this method should be atomic, * thus providing an uninterruptible way of updating an integer field. * 在obj的offset位置比较integer field和期望的值,如果相同则更新。这个方法 * 的操作应该是原子的,因此提供了一种不可中断的方式更新integer field。 * * @param obj the object containing the field to modify. * 包含要修改field的对象 * @param offset the offset of the integer field withinobj
. *obj
中整型field的偏移量 * @param expect the expected value of the field. * 希望field中存在的值 * @param update the new value of the field if it equalsexpect
. * 如果期望值expect与field的当前值相同,设置filed的值为这个新值 * @return true if the field was changed. * 如果field的值被更改返回true */ public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);
下面看看compareAndSwapInt()方法具体源码,如下:
jbooleansun::misc::Unsafe::compareAndSwapInt (jobject obj, jlong offset, jint expect, jint update){ jint *addr = (jint *)((char *)obj + offset); return compareAndSwap (addr, expect, update);}
static inline boolcompareAndSwap (volatile jint *addr, jint old, jint new_val){ jboolean result = false; spinlock lock; if ((result = (*addr == old))) *addr = new_val; return result;}
实现原理就是内存位置的值与期望值相同则将该内存位置的值更新为新值。
Unsafe类的更多源码解释:http://blog.csdn.net/zgmzyr/article/details/8902683