属性类型的原子类
类名 | 说明 |
---|---|
AtomicIntegerFieldUpdater | 原子更新整型的字段的更新器。 |
AtomicLongFieldUpdater | 原子更新长整型字段的更新器。 |
AtomicReferenceFieldUpdater | 原子更新引用类型字段的更新器。 |
AtomicReferenceFieldUpdater
AtomicReferenceFieldUpdater用来表示类中引用类型属性字段原子操作类.
操作限制
-
字段必须是volatile类型的,在线程之间共享变量时保证立即可见
-
字段的描述类型(修饰符public/protected/default/private)是与调用者与操作对象字段的关系一致
-
只能是实例变量,不能是类变量
-
只能是可修改变量,不能使final变量,因为final的语义就是不可修改
原理解析
AtomicReferenceFieldUpdater本质上使用Unsafe 对象属性相关API函数。
我们需要传入操作对象obj,原始值,预期值,和当前值。
U.compareAndSwapObject(obj, offset, expect, update);
而AtomicReferenceFieldUpdater为了描述一个类的属性操作,我们需要知道类的Class,属性的Class,以及当前操作的属性的修饰符(是否有权限)。
/**
* 属性在内存中的偏移地址
*/
private final long offset;
/**
* 操作类Class
*/
private final Class<?> cclass;
private final Class<T> tclass;
/**
* 操作类属性Class
*/
private final Class<V> vclass;
当我们创建一个AtomicReferenceFieldUpdater只需要传入表示该字段所在的类的Class,字段类型的Class,以及操作属性的名称(内部会使用反射获取字段的标识符)
/**
* 获取一个AtomicReferenceFieldUpdater实例(用来表示类中的一个属性字段)
* @param tclass 表示该字段所在的类
* @param vclass 表示该字段的类型
* @param fieldName 表示要更新的字段名
*/
@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());
}
AtomicReferenceFieldUpdaterImpl(final Class<T> tclass,
final Class<V> vclass,
final String fieldName,
final Class<?> caller) {
/** 操作类属性Field **/
final Field field;
/** 操作类属性的class **/
final Class<?> fieldClass;
/** 操作类属性修饰符 **/
final int modifiers;
try {
/** 使用反射获取对象的属性 field **/
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");
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.vclass = vclass;
this.offset = U.objectFieldOffset(field);
}
有了这些我们就可以使用CAS对类的属性操作了。
/**
* 使用CAS设置对象属性的值
*/
public final boolean compareAndSet(T obj, V expect, V update) {
accessCheck(obj);
valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
}
/**
* 使用CAS设置对象属性的值
*/
public final boolean weakCompareAndSet(T obj, V expect, V update) {
// same implementation as strong form for now
accessCheck(obj);
valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
}
/**
* 设置对象属性的值(其他线程可见)
*/
public final void set(T obj, V newValue) {
accessCheck(obj);
valueCheck(newValue);
U.putObjectVolatile(obj, offset, newValue);
}
/**
* 设置对象属性的值(其他线程不一定可见)
*/
public final void lazySet(T obj, V newValue) {
accessCheck(obj);
valueCheck(newValue);
U.putOrderedObject(obj, offset, newValue);
}
/**
* 获取对象属性的值(其他线程可见)
*/
@SuppressWarnings("unchecked")
public final V get(T obj) {
accessCheck(obj);
return (V)U.getObjectVolatile(obj, offset);
}
/**
* 使用原子的方式设置对象属性的值(CAS+循环),并返回旧值
*/
@SuppressWarnings("unchecked")
public final V getAndSet(T obj, V newValue) {
accessCheck(obj);
valueCheck(newValue);
return (V)U.getAndSetObject(obj, offset, newValue);
}
网友评论