Java的JUC的原子操做類能夠分爲四類:html
一、基本類型:AtomicInteger、AtomicLong、AtomicBooleanjava
二、數組類型:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray數組
三、引用類型:AtomicReference、AtomicStampedReference、AtomicMarkableReferenceapp
四、對象的屬性修改類型:AtomicIntegerFiledUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdaterless
這些原子類的目的是對相應的數據進行原子操做。所謂原子操做就是操做過程不會被打斷,保證數據操做是按照原子類型進行的。ide
AtomicInteger、AtomicLong、AtomicBoolean這幾個基本類型的原子類的用法和原理類似。說說AtomicLong,其做用是對長整形進行原子操做。函數
/** * * @since 1.5 * @author Doug Lea */ public class AtomicLong extends Number implements java.io.Serializable { private static final long serialVersionUID = 1927816293512124184L; // setup to use Unsafe.compareAndSwapLong for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; /** * Records whether the underlying JVM supports lockless * compareAndSwap for longs. While the Unsafe.compareAndSwapLong * method works in either case, some constructions should be * handled at Java level to avoid locking user-visible locks. */ static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); /** * Returns whether underlying JVM supports lockless CompareAndSet * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS. */ private static native boolean VMSupportsCS8(); static { try { valueOffset = unsafe.objectFieldOffset (AtomicLong.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile long value; /** * 建立值爲initialValue的AtomicLong對象 */ public AtomicLong(long initialValue) { value = initialValue; } /** * 構造函數 */ public AtomicLong() { } /** * 獲取但前置值 */ public final long get() { return value; } /** * 以原子方式設置當前值爲newValue */ public final void set(long newValue) { value = newValue; } /** * 延時設置變量值,和set差很少,只是有延遲 */ public final void lazySet(long newValue) { unsafe.putOrderedLong(this, valueOffset, newValue); } /** * 以原子方式將當前值設置爲newValue,並返回舊值 */ public final long getAndSet(long newValue) { return unsafe.getAndSetLong(this, valueOffset, newValue); } /** * 若是當前值==預期值,則以原子的方式將該設置爲給定的更新值 */ public final boolean compareAndSet(long expect, long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); } /** * 和上面效果差很少,只是不保證更新成功 */ public final boolean weakCompareAndSet(long expect, long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); } /** * 以原子的方式加1,並返回加1前的值 */ public final long getAndIncrement() { return unsafe.getAndAddLong(this, valueOffset, 1L); } /** * 以原子方式將當前值減1,並返回減1前的值 */ public final long getAndDecrement() { return unsafe.getAndAddLong(this, valueOffset, -1L); } /** * 按原子方式將當前值與delta相加,並返回相加前的值 */ public final long getAndAdd(long delta) { return unsafe.getAndAddLong(this, valueOffset, delta); } /** * 以原子方式將當前值加1,並返回加1後的值 */ public final long incrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L; } /** * 按原子方式減1,並返回減1後的值 */ public final long decrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L; } /** * 按原子方式將當前值與delta相加,並返回相加後的值 */ public final long addAndGet(long delta) { return unsafe.getAndAddLong(this, valueOffset, delta) + delta; } /** * Atomically updates the current value with the results of * applying the given function, returning the previous value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. * * @param updateFunction a side-effect-free function * @return the previous value * @since 1.8 */ public final long getAndUpdate(LongUnaryOperator updateFunction) { long prev, next; do { prev = get(); next = updateFunction.applyAsLong(prev); } while (!compareAndSet(prev, next)); return prev; } /** * Atomically updates the current value with the results of * applying the given function, returning the updated value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. * * @param updateFunction a side-effect-free function * @return the updated value * @since 1.8 */ public final long updateAndGet(LongUnaryOperator updateFunction) { long prev, next; do { prev = get(); next = updateFunction.applyAsLong(prev); } while (!compareAndSet(prev, next)); return next; } /** * Atomically updates the current value with the results of * applying the given function to the current and given values, * returning the previous value. The function should be * side-effect-free, since it may be re-applied when attempted * updates fail due to contention among threads. The function * is applied with the current value as its first argument, * and the given update as the second argument. * * @param x the update value * @param accumulatorFunction a side-effect-free function of two arguments * @return the previous value * @since 1.8 */ public final long getAndAccumulate(long x, LongBinaryOperator accumulatorFunction) { long prev, next; do { prev = get(); next = accumulatorFunction.applyAsLong(prev, x); } while (!compareAndSet(prev, next)); return prev; } /** * Atomically updates the current value with the results of * applying the given function to the current and given values, * returning the updated value. The function should be * side-effect-free, since it may be re-applied when attempted * updates fail due to contention among threads. The function * is applied with the current value as its first argument, * and the given update as the second argument. * * @param x the update value * @param accumulatorFunction a side-effect-free function of two arguments * @return the updated value * @since 1.8 */ public final long accumulateAndGet(long x, LongBinaryOperator accumulatorFunction) { long prev, next; do { prev = get(); next = accumulatorFunction.applyAsLong(prev, x); } while (!compareAndSet(prev, next)); return next; } /** * 將當前值轉換爲string類型並返回 */ public String toString() { return Long.toString(get()); } /** * 返回當前對應的int */ public int intValue() { return (int)get(); } /** * 獲取當前值對應的long值 */ public long longValue() { return get(); } /** * 以floa形式返回當前值 */ public float floatValue() { return (float)get(); } /** * 以double的形式返回當前值 */ public double doubleValue() { return (double)get(); } }
AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray三個原理和用法類似,說說AtomicIntegerArrayui
public class AtomicLongArray implements java.io.Serializable { private static final long serialVersionUID = -2308431214976778248L; private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final int base = unsafe.arrayBaseOffset(long[].class); private static final int shift; private final long[] array; static { int scale = unsafe.arrayIndexScale(long[].class); if ((scale & (scale - 1)) != 0) throw new Error("data type scale not a power of two"); shift = 31 - Integer.numberOfLeadingZeros(scale); } private long checkedByteOffset(int i) { if (i < 0 || i >= array.length) throw new IndexOutOfBoundsException("index " + i); return byteOffset(i); } private static long byteOffset(int i) { return ((long) i << shift) + base; } /** * 建立給定長度的AtomicLongArray */ public AtomicLongArray(int length) { array = new long[length]; } /** * 建立與給定數組長度相同的AtomicLongArray,並從給定數組賦值全部元素 */ public AtomicLongArray(long[] array) { // Visibility guaranteed by final field guarantees this.array = array.clone(); } /** * 返回數組長度 */ public final int length() { return array.length; } /** * 獲取位置i的值 */ public final long get(int i) { return getRaw(checkedByteOffset(i)); } private long getRaw(long offset) { return unsafe.getLongVolatile(array, offset); } /** * 設置指定位置i的值newValue */ public final void set(int i, long newValue) { unsafe.putLongVolatile(array, checkedByteOffset(i), newValue); } /** * 延遲設置指定位置的值 */ public final void lazySet(int i, long newValue) { unsafe.putOrderedLong(array, checkedByteOffset(i), newValue); } /** * 將指定位置i的值設置爲newValue,並返回原來的值 */ public final long getAndSet(int i, long newValue) { return unsafe.getAndSetLong(array, checkedByteOffset(i), newValue); } /** * 若是當前值與預期的值相同,則以原子的方式將該值設置爲給定的更新值 */ public final boolean compareAndSet(int i, long expect, long update) { return compareAndSetRaw(checkedByteOffset(i), expect, update); } private boolean compareAndSetRaw(long offset, long expect, long update) { return unsafe.compareAndSwapLong(array, offset, expect, update); } /** * */ public final boolean weakCompareAndSet(int i, long expect, long update) { return compareAndSet(i, expect, update); } /** * 以原子的方式將索引出的值加1 */ public final long getAndIncrement(int i) { return getAndAdd(i, 1); } /** * 按原子的方式將索引處的元素加1 */ public final long getAndDecrement(int i) { return getAndAdd(i, -1); } /** * 以原子方式將索引出的值與delta相加 */ public final long getAndAdd(int i, long delta) { return unsafe.getAndAddLong(array, checkedByteOffset(i), delta); } /** * 加1 */ public final long incrementAndGet(int i) { return getAndAdd(i, 1) + 1; } /** * 減1 */ public final long decrementAndGet(int i) { return getAndAdd(i, -1) - 1; } /** * 加delta */ public long addAndGet(int i, long delta) { return getAndAdd(i, delta) + delta; } /** * Atomically updates the element at index {@code i} with the results * of applying the given function, returning the previous value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. * * @param i the index * @param updateFunction a side-effect-free function * @return the previous value * @since 1.8 */ public final long getAndUpdate(int i, LongUnaryOperator updateFunction) { long offset = checkedByteOffset(i); long prev, next; do { prev = getRaw(offset); next = updateFunction.applyAsLong(prev); } while (!compareAndSetRaw(offset, prev, next)); return prev; } /** * Atomically updates the element at index {@code i} with the results * of applying the given function, returning the updated value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. * * @param i the index * @param updateFunction a side-effect-free function * @return the updated value * @since 1.8 */ public final long updateAndGet(int i, LongUnaryOperator updateFunction) { long offset = checkedByteOffset(i); long prev, next; do { prev = getRaw(offset); next = updateFunction.applyAsLong(prev); } while (!compareAndSetRaw(offset, prev, next)); return next; } /** * Atomically updates the element at index {@code i} with the * results of applying the given function to the current and * given values, returning the previous value. The function should * be side-effect-free, since it may be re-applied when attempted * updates fail due to contention among threads. The function is * applied with the current value at index {@code i} as its first * argument, and the given update as the second argument. *更新索引處的值,並返回索引處前一個值 * @param i the index * @param x the update value * @param accumulatorFunction a side-effect-free function of two arguments * @return the previous value * @since 1.8 */ public final long getAndAccumulate(int i, long x, LongBinaryOperator accumulatorFunction) { long offset = checkedByteOffset(i); long prev, next; do { prev = getRaw(offset); next = accumulatorFunction.applyAsLong(prev, x); } while (!compareAndSetRaw(offset, prev, next)); return prev; } /** * Atomically updates the element at index {@code i} with the * results of applying the given function to the current and * given values, returning the updated value. The function should * be side-effect-free, since it may be re-applied when attempted * updates fail due to contention among threads. The function is * applied with the current value at index {@code i} as its first * argument, and the given update as the second argument. * * @param i the index * @param x the update value * @param accumulatorFunction a side-effect-free function of two arguments * @return the updated value * @since 1.8 */ public final long accumulateAndGet(int i, long x, LongBinaryOperator accumulatorFunction) { long offset = checkedByteOffset(i); long prev, next; do { prev = getRaw(offset); next = accumulatorFunction.applyAsLong(prev, x); } while (!compareAndSetRaw(offset, prev, next)); return next; } /** *將當前的數組以string形式返回 */ public String toString() { int iMax = array.length - 1; if (iMax == -1) return "[]"; StringBuilder b = new StringBuilder(); b.append('['); for (int i = 0; ; i++) { b.append(getRaw(byteOffset(i))); if (i == iMax) return b.append(']').toString(); b.append(',').append(' '); } } }
public class AtomicReference<V> implements java.io.Serializable { private static final long serialVersionUID = -1848883965231344442L; //獲取Unsafe對象,Unsafe得做用是提供CAS操做 private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicReference.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile V value; /** * 用給定值建立AtomicReference */ public AtomicReference(V initialValue) { value = initialValue; } /** * 直接建立一個AtomicReference */ public AtomicReference() { } /** * 獲取當前值 */ public final V get() { return value; } /** *設置爲給定值 */ public final void set(V newValue) { value = newValue; } /** * 延遲設置 */ public final void lazySet(V newValue) { unsafe.putOrderedObject(this, valueOffset, newValue); } /** * 當前值==預期值,以原子的方式將該值設置爲給定值的更新 */ public final boolean compareAndSet(V expect, V update) { return unsafe.compareAndSwapObject(this, valueOffset, expect, update); } public final boolean weakCompareAndSet(V expect, V update) { return unsafe.compareAndSwapObject(this, valueOffset, expect, update); } /** * 設置爲給定值,並返回以前的值 */ @SuppressWarnings("unchecked") public final V getAndSet(V newValue) { return (V)unsafe.getAndSetObject(this, valueOffset, newValue); } /** * Atomically updates the current value with the results of * applying the given function, returning the previous value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. *更新值,並返回當前值指向的前一個值 * @param updateFunction a side-effect-free function * @return the previous value * @since 1.8 */ public final V getAndUpdate(UnaryOperator<V> updateFunction) { V prev, next; do { prev = get(); next = updateFunction.apply(prev); } while (!compareAndSet(prev, next)); return prev; } /** * Atomically updates the current value with the results of * applying the given function, returning the updated value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. * * @param updateFunction a side-effect-free function * @return the updated value * @since 1.8 */ public final V updateAndGet(UnaryOperator<V> updateFunction) { V prev, next; do { prev = get(); next = updateFunction.apply(prev); } while (!compareAndSet(prev, next)); return next; } /** * Atomically updates the current value with the results of * applying the given function to the current and given values, * returning the previous value. The function should be * side-effect-free, since it may be re-applied when attempted * updates fail due to contention among threads. The function * is applied with the current value as its first argument, * and the given update as the second argument. * * @param x the update value * @param accumulatorFunction a side-effect-free function of two arguments * @return the previous value * @since 1.8 */ public final V getAndAccumulate(V x, BinaryOperator<V> accumulatorFunction) { V prev, next; do { prev = get(); next = accumulatorFunction.apply(prev, x); } while (!compareAndSet(prev, next)); return prev; } /** * Atomically updates the current value with the results of * applying the given function to the current and given values, * returning the updated value. The function should be * side-effect-free, since it may be re-applied when attempted * updates fail due to contention among threads. The function * is applied with the current value as its first argument, * and the given update as the second argument. * * @param x the update value * @param accumulatorFunction a side-effect-free function of two arguments * @return the updated value * @since 1.8 */ public final V accumulateAndGet(V x, BinaryOperator<V> accumulatorFunction) { V prev, next; do { prev = get(); next = accumulatorFunction.apply(prev, x); } while (!compareAndSet(prev, next)); return next; } /** * 返回string類型的值 */ public String toString() { return String.valueOf(get()); } }
public abstract class AtomicIntegerFieldUpdater<T> { @CallerSensitive public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { return new AtomicIntegerFieldUpdaterImpl<U> (tclass, fieldName, Reflection.getCallerClass()); } /** * 受保護的無操做構造方法,供子類使用 */ protected AtomicIntegerFieldUpdater() { } /** * 若是當前值==預期值,則以原子的方式將此更新器所管理的給定對象的字段設置爲給定的更新值 */ public abstract boolean compareAndSet(T obj, int expect, int update); public abstract boolean weakCompareAndSet(T obj, int expect, int update); /** * 將此更新器管理的給定對象的字段設置爲給定更新值 */ public abstract void set(T obj, int newValue); /** *最後將此更新管理器給定對象的字段設置爲給定更新值 */ public abstract void lazySet(T obj, int newValue); /** * 獲取此更新管理器管理的給定對象的字段中保持的當前值 */ public abstract int get(T obj); /** * 將此更新管理器的給定對象的字段以原子方式設定爲給定值,並返回舊值 */ public int getAndSet(T obj, int newValue) { int prev; do { prev = get(obj); } while (!compareAndSet(obj, prev, newValue)); return prev; } /** * 以原子方式將此更新管理的給定對象字段的當前值加1 */ public int getAndIncrement(T obj) { int prev, next; do { prev = get(obj); next = prev + 1; } while (!compareAndSet(obj, prev, next)); return prev; } /** * 以原子方式將此更新管理器給定對象字段的當前值減1 */ public int getAndDecrement(T obj) { int prev, next; do { prev = get(obj); next = prev - 1; } while (!compareAndSet(obj, prev, next)); return prev; } /** * 以原子方式將給定值添加到此更新管理器給定字段的當前值 */ public int getAndAdd(T obj, int delta) { int prev, next; do { prev = get(obj); next = prev + delta; } while (!compareAndSet(obj, prev, next)); return prev; } /** * 以原子方式將此更新管理器的給定對象字段當前值加1 */ public int incrementAndGet(T obj) { int prev, next; do { prev = get(obj); next = prev + 1; } while (!compareAndSet(obj, prev, next)); return next; } /** * 以原子方式將此更新管理器的給定對象字段當前值減1 */ public int decrementAndGet(T obj) { int prev, next; do { prev = get(obj); next = prev - 1; } while (!compareAndSet(obj, prev, next)); return next; } /** * Atomically adds the given value to the current value of the field of * the given object managed by this updater. * * @param obj An object whose field to get and set * @param delta the value to add * @return the updated value */ public int addAndGet(T obj, int delta) { int prev, next; do { prev = get(obj); next = prev + delta; } while (!compareAndSet(obj, prev, next)); return next; } /** * Atomically updates the field of the given object managed by this updater * with the results of applying the given function, returning the previous * value. The function should be side-effect-free, since it may be * re-applied when attempted updates fail due to contention among threads. * * @param obj An object whose field to get and set * @param updateFunction a side-effect-free function * @return the previous value * @since 1.8 */ public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) { int prev, next; do { prev = get(obj); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(obj, prev, next)); return prev; } /** * Atomically updates the field of the given object managed by this updater * with the results of applying the given function, returning the updated * value. The function should be side-effect-free, since it may be * re-applied when attempted updates fail due to contention among threads. * */ public final int updateAndGet(T obj, IntUnaryOperator updateFunction) { int prev, next; do { prev = get(obj); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(obj, prev, next)); return next; } /** * Atomically updates the field of the given object managed by this * updater with the results of applying the given function to the * current and given values, returning the previous value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. The * function is applied with the current value as its first argument, * and the given update as the second argument. */ public final int getAndAccumulate(T obj, int x, IntBinaryOperator accumulatorFunction) { int prev, next; do { prev = get(obj); next = accumulatorFunction.applyAsInt(prev, x); } while (!compareAndSet(obj, prev, next)); return prev; } /** * Atomically updates the field of the given object managed by this * updater with the results of applying the given function to the * current and given values, returning the updated value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. The * function is applied with the current value as its first argument, * and the given update as the second argument. */ public final int accumulateAndGet(T obj, int x, IntBinaryOperator accumulatorFunction) { int prev, next; do { prev = get(obj); next = accumulatorFunction.applyAsInt(prev, x); } while (!compareAndSet(obj, prev, next)); return next; } /** * Standard hotspot implementation using intrinsics */ private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> { private static final Unsafe unsafe = Unsafe.getUnsafe(); private final long offset; private final Class<T> tclass; private final Class<?> cclass; AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName, final Class<?> caller) { final Field field; final int modifiers; try { field = AccessController.doPrivileged( new PrivilegedExceptionAction<Field>() { public Field run() throws NoSuchFieldException { return tclass.getDeclaredField(fieldName); } }); modifiers = field.getModifiers(); sun.reflect.misc.ReflectUtil.ensureMemberAccess( caller, tclass, null, modifiers); ClassLoader cl = tclass.getClassLoader(); ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } } catch (PrivilegedActionException pae) { throw new RuntimeException(pae.getException()); } catch (Exception ex) { throw new RuntimeException(ex); } Class<?> fieldt = field.getType(); if (fieldt != int.class) throw new IllegalArgumentException("Must be integer type"); if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); this.cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller : null; this.tclass = tclass; offset = unsafe.objectFieldOffset(field); } /** * Returns true if the second classloader can be found in the first * classloader's delegation chain. * Equivalent to the inaccessible: first.isAncestor(second). */ private static boolean isAncestor(ClassLoader first, ClassLoader second) { ClassLoader acl = first; do { acl = acl.getParent(); if (second == acl) { return true; } } while (acl != null); return false; } }
經過「volatile」和「Unsafe提供得CSA函數實現」原子操做。this
1)value是volatile類型,這保證了:當某線程修改value得值時,其餘線程看到的value值都是最新的value值,即修改以後的value值spa
2)經過CAS設置value,這保證了:當某線程經過CAS函數設置value值得時候,它得操做是原子的,即線程在操做value時不會被中斷。