Atomic
针对基本数据类型的单个变量
AtomicInteger
// 就是对 value 执行操作
public class AtomicInteger extends Number implements java.io.Serializable {
...
// 拿到 Unsafe 类
private static final Unsafe unsafe = Unsafe.getUnsafe();
// 偏移量: 字段相对于对象内存地址的偏移量
private static final long valueOffset;
static {
try {
// 反射的方式获取 value 的偏移量 这个偏移量可以用于后续的无锁操作
valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
// 其他的方法都是直接调用 native 的方法实现的,如:getAndIncrement、getAndDecrement、compareAndSet、getAndSet等
...
// 以此为例
/*
如果指定位置上的当前值==预期值,则自动将该值设置为给定的更新值。
形参:
expect期望值 update ——新值
返回值:
如果cas 成功则为true 。返回 False 表示指定位置上的实际值不等于期望值。
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
}
AtomicBoolean
public class AtomicBoolean implements java.io.Serializable {
...
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset(AtomicBoolean.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
...
//如果当前值==预期值,则自动将该值设置为给定的更新值。
public final boolean compareAndSet(boolean expect, boolean update) { // 这里的是 boolean 类型的值
// 将boolean 转为 int 值进行 cas
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
}
AtomicLong
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;
/**
*
记录底层 JVM 是否支持 long 的无锁compareAndSwap。
虽然 Unsafe.compareAndSwapLong 方法在任一情况下都有效,但应在 Java 级别处理某些构造以避免锁定用户可见的锁。
*/
static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
/**
返回底层 JVM 是否支持 long 的无锁 CompareAndSet。仅调用一次并缓存在 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;
...
/*
如果当前值==预期值,则自动将该值设置为给定的更新值。
形参:
expect期望值 update ——新值
返回值:
如果成功则为true 。返回 False 表示实际值不等于期望值。
*/
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
...
}
针对引用类型的单个变量
通过对 Object中的属性进行反射 + CAS 支持属性原子操作
AtomicReference
public class AtomicReference<V> implements java.io.Serializable {
private static final long serialVersionUID = -1848883965231344442L;
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;
...
public final boolean compareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
...
}
AtomicStampedReference
public class AtomicStampedReference<V> {
private static class Pair<T> {
final T reference;
final int stamp; // 解决了 cas 的 ABA 问题
private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
static <T> Pair<T> of(T reference, int stamp) {
return new Pair<T>(reference, stamp);
}
}
private volatile Pair<V> pair;
...
/*
如果当前引用==到预期引用并且当前标记等于预期标记,则以原子方式将引用和标记的值设置为给定更新值。
形参:
expectedReference – 参考的预期值
newReference – 参考的新值
expectedStamp – 邮票的预期值
newStamp – 邮票的新值
返回值:
如果成功则为true
*/
public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
// 将当前的pair赋值给变量current
Pair<V> current = pair;
return
expectedReference == current.reference && //当前的值是 预期的值
expectedStamp == current.stamp && // 当前的stamp 也是预期的值
((newReference == current.reference && // 新值是 当前的值
newStamp == current.stamp) || // stamp 的值是 当前的值
//前两个都是false 那么就 cas 的 将current替换为Pair.of(newReference, newStamp)
casPair(current, Pair.of(newReference, newStamp)));
}
...
/*
使用CAS操作来原子性地更新AtomicStampedReference对象中的pair字段的值。
*/
// 获取了一个用于执行底层操作的Unsafe实例。
private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
//获取了pair字段在AtomicStampedReference类中的偏移量。
private static final long pairOffset = objectFieldOffset(UNSAFE, "pair", AtomicStampedReference.class);
// 使用UNSAFE.compareAndSwapObject方法来比较并交换对象的pair字段的值。如果当前的pair字段的值等于cmp,则将其更新为val并返回true,否则返回false。
private boolean casPair(Pair<V> cmp, Pair<V> val) {
return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
}
//获取指定类中指定字段的偏移量。
static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
String field, Class<?> klazz) {
try {
//通过反射获取字段对象,然后使用UNSAFE.objectFieldOffset方法获取字段的偏移量。
return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
} catch (NoSuchFieldException e) {
// 如果字段不存在,则抛出NoSuchFieldError异常。
NoSuchFieldError error = new NoSuchFieldError(field);
error.initCause(e);
throw error;
}
}
}
AtomicMarkableReference
public class AtomicMarkableReference<V> {
private static class Pair<T> {
final T reference;
final boolean mark;
private Pair(T reference, boolean mark) {
this.reference = reference;
this.mark = mark;
}
static <T> Pair<T> of(T reference, boolean mark) {
return new Pair<T>(reference, mark);
}
}
private volatile Pair<V> pair;
...
/*
如果当前引用==到预期引用并且当前标记等于预期标记,则以原子方式将引用和标记的值设置为给定更新值。
形参:
expectedReference – 参考的预期值 newReference – 参考的新值 expectedMark – 标记的期望值 newMark – 标记的新值
返回值:
如果成功则为true
*/
public boolean compareAndSet(V expectedReference,
V newReference,
boolean expectedMark,
boolean newMark) {
Pair<V> current = pair;
return
expectedReference == current.reference &&
expectedMark == current.mark &&
((newReference == current.reference &&
newMark == current.mark) ||
casPair(current, Pair.of(newReference, newMark)));
}
...
private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
private static final long pairOffset =
objectFieldOffset(UNSAFE, "pair", AtomicMarkableReference.class);
private boolean casPair(Pair<V> cmp, Pair<V> val) {
return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
}
static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
String field, Class<?> klazz) {
try {
return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
} catch (NoSuchFieldException e) {
// Convert Exception to corresponding Error
NoSuchFieldError error = new NoSuchFieldError(field);
error.initCause(e);
throw error;
}
}
}
针对的是多个变量
都是通过下标去操作数组中的元素
AtomicIntegerArray
public class AtomicIntegerArray implements java.io.Serializable {
private static final long serialVersionUID = 2862133569453604235L;
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;
// 计算int数组的元素大小,并确定位移量
static {
// 使用unsafe.arrayIndexScale(int[].class)函数获取int数组元素的大小,存储在变量scale中。
int scale = unsafe.arrayIndexScale(int[].class);
// 它通过检查scale是否是2的幂次方来确保元素大小是2的幂次方。如果不是,就会抛出一个错误。
if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two");
// 31 - Integer.numberOfLeadingZeros(scale)函数计算scale的二进制表示中前导零的数量,
// 得到位移量,并将结果存储在shift变量中。
shift = 31 - Integer.numberOfLeadingZeros(scale);
}
...
/*
如果当前值==预期值,则自动将位置i处的元素设置为给定的更新值。
形参:
i – 索引 expect期望值 update ——新值
返回值:
如果成功则为true 。返回 False 表示实际值不等于期望值。
*/
public final boolean compareAndSet(int i, int expect, int update) {
return compareAndSetRaw(checkedByteOffset(i), expect, update);
}
private boolean compareAndSetRaw(long offset, int expect, int update) {
return unsafe.compareAndSwapInt(array, offset, expect, update);
}
//接受一个整数参数i,并返回一个长整型值。
private long checkedByteOffset(int i) {
//检查参数i是否小于0或大于等于数组array的长度。如果是,则抛出一个IndexOutOfBoundsException异常,异常信息中包含索引i的值。
if (i < 0 || i >= array.length)
throw new IndexOutOfBoundsException("index " + i);
//调用 byteOffset(i) 来计算并返回字节偏移量
return byteOffset(i);
}
// 将整数 i 左移 shift 位,并将结果与变量 base 相加,然后将其转换为长整型值返回
private static long byteOffset(int i) {
return ((long) i << shift) + base;
}
...
}
AtomicLongArray
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;
}
/*
如果当前值==预期值,则自动将位置i处的元素设置为给定的更新值。
形参:
i – 索引 expect期望值 update ——新值
返回值:
如果成功则为true 。返回 False 表示实际值不等于期望值。
*/
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);
}
...
}
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.getUnsafe() 方法获取一个 Unsafe 对象的实例,并将其赋值给静态变量 unsafe。
unsafe = Unsafe.getUnsafe();
// 使用 unsafe.objectFieldOffset() 方法获取 AtomicReferenceArray 类中名为 "array" 的字段的偏移量,并将其赋值给静态变量 arrayFieldOffset。
arrayFieldOffset = unsafe.objectFieldOffset(AtomicReferenceArray.class.getDeclaredField("array"));
// 使用 unsafe.arrayBaseOffset() 方法获取 Object[] 类的基本偏移量,并将其赋值给静态变量 base。
base = unsafe.arrayBaseOffset(Object[].class);
// 使用 unsafe.arrayIndexScale() 方法获取 Object[] 类的索引缩放因子,并将其赋值给局部变量 scale。
int scale = unsafe.arrayIndexScale(Object[].class);
// 如果 scale 不是 2 的幂次方,则抛出一个 异常
if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two");
// 根据 scale 计算 shift 的值,该值表示 scale 的二进制表示中最高位的索引。
shift = 31 - Integer.numberOfLeadingZeros(scale);
} catch (Exception e) {
throw new Error(e);
}
}
/*
如果当前值==预期值,则自动将位置i处的元素设置为给定的更新值。
形参:
i – 索引 expect期望值 update ——新值
返回值:
如果成功则为true 。返回 False 表示实际值不等于期望值。
*/
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;
}
...
public final boolean compareAndSet(int i, E expect, E update) {
return compareAndSetRaw(checkedByteOffset(i), expect, update);
}
private boolean compareAndSetRaw(long offset, E expect, E update) {
return unsafe.compareAndSwapObject(array, offset, expect, update);
}
...
}
针对对象类型中的某个属性
AtomicIntegerFieldUpdater
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());
}
/*
如果当前值==预期值,则自动将此更新程序管理的给定对象的字段设置为给定的更新值。该方法相对于对compareAndSet和set其他调用而言保证是原子的,但不一定相对于字段中的其他更改。
形参:
obj – 要有条件设置其字段的对象 expect期望值 update ——新值
返回值:如果成功则为true
转发: ClassCastException – 如果obj不是拥有构造函数中建立的字段的类的实例
*/
public abstract boolean compareAndSet(T obj, int expect, int update);
private static final class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<?> cclass;
private final Class<T> tclass;
// 通过反射获取指定类中的整型字段,并创建一个AtomicIntegerFieldUpdater对象来实现对该字段的原子性更新操作
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
final String fieldName,
final Class<?> caller) {
final Field field;
final int modifiers;
try {
// 代码通过反射获取了要更新的字段对象,这个字段是在指定的类(tclass)中通过字段名(fieldName)来获取的
field = AccessController.doPrivileged(
new PrivilegedExceptionAction<Field>() {
public Field run() throws NoSuchFieldException {
return tclass.getDeclaredField(fieldName);
}
});
// 检查字段的修饰符(modifiers)来确保它是volatile类型,并且字段的类型是int类型,否则会抛出异常。
modifiers = field.getModifiers();
//检查字段的访问权限。如果字段是protected字段,并且访问者(caller)是tclass的子类或者包内的类,那么将使用caller作为访问者,否则使用tclass作为访问者。
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);
}
if (field.getType() != 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) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
//使用UNSAFE.objectFieldOffset(field)方法获取字段的偏移量,并将其保存在offset字段中,以便后续的原子性更新操作中使用。
this.offset = U.objectFieldOffset(field);
}
public final boolean compareAndSet(T obj, int expect, int update) {
accessCheck(obj);
return U.compareAndSwapInt(obj, offset, expect, update);
}
//检查目标参数是否是 cclass 的实例。失败时,抛出原因。
private final void accessCheck(T obj) {
if (!cclass.isInstance(obj))
throwAccessCheckException(obj);
}
//如果 accessCheck 由于受保护的访问而失败,则抛出访问异常,否则抛出 ClassCastException。
private final void throwAccessCheckException(T obj) {
if (cclass == tclass)
throw new ClassCastException();
else
throw new RuntimeException(
new IllegalAccessException(
"Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()));
}
}
}
AtomicLongFieldUpdater
public abstract class AtomicLongFieldUpdater<T> {
@CallerSensitive
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
String fieldName) {
Class<?> caller = Reflection.getCallerClass();
if (AtomicLong.VM_SUPPORTS_LONG_CAS)
return new CASUpdater<U>(tclass, fieldName, caller);
else
return new LockedUpdater<U>(tclass, fieldName, caller);
}
public abstract boolean compareAndSet(T obj, long expect, long update);
private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<?> cclass;
private final Class<T> tclass;
CASUpdater(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);
}
if (field.getType() != long.class)
throw new IllegalArgumentException("Must be long type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.offset = U.objectFieldOffset(field);
}
public final boolean compareAndSet(T obj, long expect, long update) {
accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
}
}
private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
LockedUpdater(final Class<T> tclass, final String fieldName,
final Class<?> caller) {
Field field = null;
int modifiers = 0;
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);
}
if (field.getType() != long.class)
throw new IllegalArgumentException("Must be long type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.offset = U.objectFieldOffset(field);
}
public final boolean compareAndSet(T obj, long expect, long update) {
accessCheck(obj);
synchronized (this) {
long v = U.getLong(obj, offset);
if (v != expect)
return false;
U.putLong(obj, offset, update);
return true;
}
}
}
}
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());
}
public abstract boolean compareAndSet(T obj, V expect, V update);
private static final class AtomicReferenceFieldUpdaterImpl<T,V>
extends AtomicReferenceFieldUpdater<T,V> {
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<?> cclass;
private final Class<T> tclass;
private final Class<V> vclass;
AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
final Class<V> vclass,
final String fieldName,
final Class<?> caller) {
final Field field;
final Class<?> fieldClass;
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);
}
fieldClass = field.getType();
} catch (PrivilegedActionException pae) {
throw new RuntimeException(pae.getException());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
if (vclass != fieldClass)
throw new ClassCastException();
if (vclass.isPrimitive())
throw new IllegalArgumentException("Must be reference type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.vclass = vclass;
this.offset = U.objectFieldOffset(field);
}
public final boolean compareAndSet(T obj, V expect, V update) {
accessCheck(obj);
valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
}
}
}
在单个cas + 自旋的操作下会有性能问题,所以采用分治的思想 将一个变量的累加分散到一个cells 数组中进行,随后用过sum 方法进行聚合,返回用户