Java多线程:“JUC原子类”03之AtomicLongArray原子类2014-06-02 cnblogs skywang12345AtomicLongArray介绍和函数列表在"Java多线程系列--“JUC原子类”02之 AtomicLong原子类"中介绍过, AtomicLong是作用是对长整形进行原子操作。而AtomicLongArray的作用则是对"长整形数组" 进行原子操作。AtomicLongArray函数列表
// 创建给定长度的新 AtomicLongArray。AtomicLongArray(int length)// 创建与给定数组具有相同长度的新 AtomicLongArray,并从给定数组复制其所有元素。AtomicLongArray(long[] array)// 以原子方式将给定值添加到索引 i 的元素。long addAndGet(int i, long delta)// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。boolean compareAndSet(int i, long expect, long update)// 以原子方式将索引 i 的元素减1。long decrementAndGet(int i)// 获取位置 i 的当前值。long get(int i)// 以原子方式将给定值与索引 i 的元素相加。long getAndAdd(int i, long delta)// 以原子方式将索引 i 的元素减 1。long getAndDecrement(int i)// 以原子方式将索引 i 的元素加 1。long getAndIncrement(int i)// 以原子方式将位置 i 的元素设置为给定值,并返回旧值。long getAndSet(int i, long newValue)// 以原子方式将索引 i 的元素加1。long incrementAndGet(int i)// 最终将位置 i 的元素设置为给定值。void lazySet(int i, long newValue)// 返回该数组的长度。int length()// 将位置 i 的元素设置为给定值。void set(int i, long newValue)// 返回数组当前值的字符串表示形式。String toString()// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。booleanweakCompareAndSet(int i, long expect, long update)
AtomicLongArray源码分析(基于JDK1.7.0_40)AtomicLongArray的完整源码
/* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * *//* * * * * * * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */package java.util.concurrent.atomic;import sun.misc.Unsafe;import java.util.*;/** * A {@code long} array in which elements may be updated atomically. * See the {@link java.util.concurrent.atomic} package specification * for description of the properties of atomic variables. * @since 1.5 * @author Doug Lea */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;}/** * Creates a new AtomicLongArray of the given length, with all * elements initially zero. * * @param length the length of the array */public AtomicLongArray(int length) {array = new long[length];}/** * Creates a new AtomicLongArray with the same length as, and * all elements copied from, the given array. * * @param array the array to copy elements from * @throws NullPointerException if array is null */public AtomicLongArray(long[] array) {// Visibility guaranteed by final field guaranteesthis.array = array.clone();}/** * Returns the length of the array. * * @return the length of the array */public final int length() {return array.length;}/** * Gets the current value at position {@code i}. * * @param i the index * @return the current value */public final long get(int i) {return getRaw(checkedByteOffset(i));}private long getRaw(long offset) {return unsafe.getLongVolatile(array, offset);}/** * Sets the element at position {@code i} to the given value. * * @param i the index * @param newValue the new value */public final void set(int i, long newValue) {unsafe.putLongVolatile(array, checkedByteOffset(i), newValue);}/** * Eventually sets the element at position {@code i} to the given value. * * @param i the index * @param newValue the new value * @since 1.6 */public final void lazySet(int i, long newValue) {unsafe.putOrderedLong(array, checkedByteOffset(i), newValue);}/** * Atomically sets the element at position {@code i} to the given value * and returns the old value. * * @param i the index * @param newValue the new value * @return the previous value */public final long getAndSet(int i, long newValue) {long offset = checkedByteOffset(i);while (true) {long current = getRaw(offset);if (compareAndSetRaw(offset, current, newValue))return current;}}/** * Atomically sets the element at position {@code i} to the given * updated value if the current value {@code ==} the expected value. * * @param i the index * @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 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);}/** * Atomically sets the element at position {@code i} to the given * updated value if the current value {@code ==} the expected value. * * <p>May <a href="package-summary.html#Spurious">fail spuriously</a> * and does not provide ordering guarantees, so is only rarely an * appropriate alternative to {@code compareAndSet}. * * @param i the index * @param expect the expected value * @param update the new value * @return true if successful. */public final boolean weakCompareAndSet(int i, long expect, long update) {return compareAndSet(i, expect, update);}/** * Atomically increments by one the element at index {@code i}. * * @param i the index * @return the previous value */public final long getAndIncrement(int i) {return getAndAdd(i, 1);}/** * Atomically decrements by one the element at index {@code i}. * * @param i the index * @return the previous value */public final long getAndDecrement(int i) {return getAndAdd(i, -1);}/** * Atomically adds the given value to the element at index {@code i}. * * @param i the index * @param delta the value to add * @return the previous value */public final long getAndAdd(int i, long delta) {long offset = checkedByteOffset(i);while (true) {long current = getRaw(offset);if (compareAndSetRaw(offset, current, current + delta))return current;}}/** * Atomically increments by one the element at index {@code i}. * * @param i the index * @return the updated value */public final long incrementAndGet(int i) {return addAndGet(i, 1);}/** * Atomically decrements by one the element at index {@code i}. * * @param i the index * @return the updated value */public final long decrementAndGet(int i) {return addAndGet(i, -1);}/** * Atomically adds the given value to the element at index {@code i}. * * @param i the index * @param delta the value to add * @return the updated value */public long addAndGet(int i, long delta) {long offset = checkedByteOffset(i);while (true) {long current = getRaw(offset);long next = current + delta;if (compareAndSetRaw(offset, current, next))return next;}}/** * Returns the String representation of the current values of array. * @return the String representation of the current values of array */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(" ");}}}