Atomic
Posted virgosnail
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Atomic相关的知识,希望对你有一定的参考价值。
类的小工具包,支持在单个变量上解除锁的线程安全编程。事实上,此包中的类可将 volatile 值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类.
传送门 : 并发编程网 Java中的Atomic包使用指南
一. 使用原子方式更新的指定元素的值
1. AtomicBoolean
public class AtomicBoolean extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; // Unsafe类使Java拥有了像C语言的指针一样操作内存空间的能力 private static final Unsafe unsafe = Unsafe.getUnsafe(); // 记录value字段相对于对象的起始内存地址的字节偏移量,主要是为了在更新操作在内存中找到value的位置,方便比较。 private static final long valueOffset; // 内存值为 int 类型的 0 或 1 private volatile int value; static { try { // 获取value字段相对于对象的起始内存地址的字节偏移量 valueOffset = unsafe.objectFieldOffset(AtomicBoolean.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } public AtomicBoolean(boolean initialValue) { value = initialValue ? 1 : 0; } }
2. AtomicInteger
使用 int 类型的 value 表示实际的值
3. AtomicLong
使用 long 类型的 value 表示实际的值
// AtomicLongFieldUpdater 中会根据此字段而使用不同的实现类 static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
4. AtomicReference<V>
使用 V 类型的 value 表示实际的值
5. AtomicIntegerArray
public class AtomicIntegerArray implements java.io.Serializable { private static final long serialVersionUID = -2308431214976778248L; private static final Unsafe unsafe = Unsafe.getUnsafe(); // 数组中第一个元素的偏移地址 也就是数组所在的基地址 private static final int base = unsafe.arrayBaseOffset(int[].class); // private static final int shift; // private final int[] array; static { // 数组中元素的宽度,int占4个byte,所以此处scale=4 int scale = unsafe.arrayIndexScale(int[].class); if ((scale & (scale - 1)) != 0) // 数据类型规模不是2的幂 throw new Error("data type scale not a power of two"); // numberOfLeadingZeros() 在指定 int 值的二进制补码表示形式中最高位(最左边)的 1 位之前,返回零位的数量 // 31减去前导零(数字变成二进制后前面0的个数),这里shift 为 2 shift = 31 - Integer.numberOfLeadingZeros(scale); } // i 数组下标 public final int get(int i) { return getRaw(checkedByteOffset(i)); } // offset 指定下标的元素相对于 array 的偏移量 private long getRaw(long offset) { return unsafe.getLongVolatile(array, offset); } // 判断下标是否越界 private long checkedByteOffset(int i) { if (i < 0 || i >= array.length) throw new IndexOutOfBoundsException("index " + i); return byteOffset(i); } // 返回指定下标的元素相对于 array 的偏移量 private static long byteOffset(int i) { // 基地址 + (第 i 个元素) i * 4(一个int4个byte) return ((long) i << shift) + base; } }
6. AtomicLongArray
private final long[] array;
7. AtomicReferenceArray
public class AtomicReferenceArray<E> implements java.io.Serializable { private static final long serialVersionUID = -6209656149925076980L; private static final Unsafe unsafe; private static final int base; private static final int shift; private static final long arrayFieldOffset; private final Object[] array; // must have exact type Object[] static { try { unsafe = Unsafe.getUnsafe(); // 获取 array 相对于对象的偏移量 arrayFieldOffset = unsafe.objectFieldOffset (AtomicReferenceArray.class.getDeclaredField("array")); base = unsafe.arrayBaseOffset(Object[].class); int scale = unsafe.arrayIndexScale(Object[].class); if ((scale & (scale - 1)) != 0) throw new Error("data type scale not a power of two"); shift = 31 - Integer.numberOfLeadingZeros(scale); } catch (Exception e) { throw new Error(e); } } }
二. 基于反射的实用工具,可以对指定类的指定 volatile int
字段进行原子更新(具体实现方式请查看源码)
8. AtomicIntegerFieldUpdater
原子方式更新对象中指定Integer类型的字段值
public abstract class AtomicIntegerFieldUpdater<T> { // 构造方法同一个package及子类可调用 protected AtomicIntegerFieldUpdater() { } // AtomicIntegerFieldUpdater是一个抽象类,但是它内部有一个private final类型的默认子类, // 所以在调用newUpdater的时候,返回一个 AtomicIntegerFieldUpdaterImpl 实例 // 一般通过该实例调用相关方法 @CallerSensitive public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName, Reflection.getCallerClass()); } } // 示例 public class Demo { volatile int number; public static void main(String[] args) { AtomicIntegerFieldUpdater<Demo> newUpdater = AtomicIntegerFieldUpdater.newUpdater(Demo.class, "number"); newUpdater.incrementAndGet(new Demo()); } }
9. AtomicLongFieldUpdater
原子方式更新对象中指定Long类型的字段值
public abstract class AtomicLongFieldUpdater<T> { @CallerSensitive public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { Class<?> caller = Reflection.getCallerClass(); // 虚拟机是否支持Long类型的CAS操作 if (AtomicLong.VM_SUPPORTS_LONG_CAS) return new CASUpdater<U>(tclass, fieldName, caller); else return new LockedUpdater<U>(tclass, fieldName, caller); } }
10. AtomicReferenceFieldUpdater
原子方式更新对象中指定引用类型的字段值
public abstract class AtomicReferenceFieldUpdater<T,V> { @CallerSensitive public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) { return new AtomicReferenceFieldUpdaterImpl<U,W> (tclass, vclass, fieldName, Reflection.getCallerClass()); } }
以上是关于Atomic的主要内容,如果未能解决你的问题,请参考以下文章