AtomicLongFieldUpdater介绍和函数列表
AtomicLongFieldUpdater可以对指定"类的 'volatile long'类型的成员"进行原子更新。它是基于反射原理实现的。
AtomicLongFieldUpdater函数列表
// 受保护的无操作构造方法,供子类使用。 protected AtomicLongFieldUpdater() // 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。 long addAndGet(T obj, long delta) // 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。 abstract boolean compareAndSet(T obj, long expect, long update) // 以原子方式将此更新器管理的给定对象字段当前值减 1。 long decrementAndGet(T obj) // 获取此更新器管理的在给定对象的字段中保持的当前值。 abstract long get(T obj) // 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。 long getAndAdd(T obj, long delta) // 以原子方式将此更新器管理的给定对象字段当前值减 1。 long getAndDecrement(T obj) // 以原子方式将此更新器管理的给定对象字段的当前值加 1。 long getAndIncrement(T obj) // 将此更新器管理的给定对象的字段以原子方式设置为给定值,并返回旧值。 long getAndSet(T obj, long newValue) // 以原子方式将此更新器管理的给定对象字段当前值加 1。 long incrementAndGet(T obj) // 最后将此更新器管理的给定对象的字段设置为给定更新值。 abstract void lazySet(T obj, long newValue) // 为对象创建并返回一个具有给定字段的更新器。 static AtomicLongFieldUpdater newUpdater(Class tclass, String fieldName) // 将此更新器管理的给定对象的字段设置为给定更新值。 abstract void set(T obj, long newValue) // 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。 abstract boolean weakCompareAndSet(T obj, long expect, long update)
AtomicLongFieldUpdater示例
// LongTest.java的源码
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
public class LongFieldTest {
public static void main(String[] args) {
// 获取Person的class对象
Class cls = Person.class;
// 新建AtomicLongFieldUpdater对象,传递参数是“class对象”和“long类型在类中对应的名称”
AtomicLongFieldUpdater mAtoLong = AtomicLongFieldUpdater.newUpdater(cls, "id");
Person person = new Person(12345678L);
// 比较person的"id"属性,如果id的值为12345678L,则设置为1000。
mAtoLong.compareAndSet(person, 12345678L, 1000);
System.out.println("id="+person.getId());
}
}
class Person {
volatile long id;
public Person(long id) {
this.id = id;
}
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
}
运行结果:
id=1000
AtomicLongFieldUpdater源码分析(基于JDK1.7.0_40)
AtomicLongFieldUpdater完整源码
package java.util.concurrent.atomic; import java.lang.reflect.*; import sun.misc.Unsafe; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; public abstract class AtomicReferenceFieldUpdater{ @CallerSensitive public static AtomicReferenceFieldUpdater newUpdater(Class tclass, Class vclass, String fieldName) { return new AtomicReferenceFieldUpdaterImpl(tclass, vclass, fieldName, Reflection.getCallerClass()); } protected AtomicReferenceFieldUpdater() { } public abstract boolean compareAndSet(T obj, V expect, V update); public abstract boolean weakCompareAndSet(T obj, V expect, V update); public abstract void set(T obj, V newValue); public abstract void lazySet(T obj, V newValue); public abstract V get(T obj); public V getAndSet(T obj, V newValue) { for (;;) { V current = get(obj); if (compareAndSet(obj, current, newValue)) return current; } } private static final class AtomicReferenceFieldUpdaterImpl extends AtomicReferenceFieldUpdater { private static final Unsafe unsafe = Unsafe.getUnsafe(); private final long offset; private final Class tclass; private final Class vclass; private final Class cclass; AtomicReferenceFieldUpdaterImpl(Class tclass, Class vclass, String fieldName, Class> caller) { Field field = null; Class fieldClass = null; int modifiers = 0; try { field = tclass.getDeclaredField(fieldName); modifiers = field.getModifiers(); sun.reflect.misc.ReflectUtil.ensureMemberAccess( caller, tclass, null, modifiers); sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); fieldClass = field.getType(); } catch (Exception ex) { throw new RuntimeException(ex); } if (vclass != fieldClass) throw new ClassCastException(); if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); this.cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller : null; this.tclass = tclass; if (vclass == Object.class) this.vclass = null; else this.vclass = vclass; offset = unsafe.objectFieldOffset(field); } void targetCheck(T obj) { if (!tclass.isInstance(obj)) throw new ClassCastException(); if (cclass != null) ensureProtectedAccess(obj); } void updateCheck(T obj, V update) { if (!tclass.isInstance(obj) || (update != null && vclass != null && !vclass.isInstance(update))) throw new ClassCastException(); if (cclass != null) ensureProtectedAccess(obj); } public boolean compareAndSet(T obj, V expect, V update) { if (obj == null || obj.getClass() != tclass || cclass != null || (update != null && vclass != null && vclass != update.getClass())) updateCheck(obj, update); return unsafe.compareAndSwapObject(obj, offset, expect, update); } public boolean weakCompareAndSet(T obj, V expect, V update) { // same implementation as strong form for now if (obj == null || obj.getClass() != tclass || cclass != null || (update != null && vclass != null && vclass != update.getClass())) updateCheck(obj, update); return unsafe.compareAndSwapObject(obj, offset, expect, update); } public void set(T obj, V newValue) { if (obj == null || obj.getClass() != tclass || cclass != null || (newValue != null && vclass != null && vclass != newValue.getClass())) updateCheck(obj, newValue); unsafe.putObjectVolatile(obj, offset, newValue); } public void lazySet(T obj, V newValue) { if (obj == null || obj.getClass() != tclass || cclass != null || (newValue != null && vclass != null && vclass != newValue.getClass())) updateCheck(obj, newValue); unsafe.putOrderedObject(obj, offset, newValue); } public V get(T obj) { if (obj == null || obj.getClass() != tclass || cclass != null) targetCheck(obj); return (V)unsafe.getObjectVolatile(obj, offset); } private void ensureProtectedAccess(T obj) { if (cclass.isInstance(obj)) { return; } 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() ) ); } } }
下面分析LongFieldTest.java的流程。
1. newUpdater()
newUpdater()的源码如下:
public static AtomicLongFieldUpdater newUpdater(Class tclass, String fieldName) {
Class> caller = Reflection.getCallerClass();
if (AtomicLong.VM_SUPPORTS_LONG_CAS)
return new CASUpdater(tclass, fieldName, caller);
else
return new LockedUpdater(tclass, fieldName, caller);
}
说明:newUpdater()的作用是获取一个AtomicIntegerFieldUpdater类型的对象。
它实际上返回的是CASUpdater对象,或者LockedUpdater对象;具体返回哪一个类取决于JVM是否支持long类型的CAS函数。CASUpdater和LockedUpdater都是AtomicIntegerFieldUpdater的子类,它们的实现类似。下面以CASUpdater来进行说明。
CASUpdater类的源码如下:
public boolean compareAndSet(T obj, long expect, long update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.compareAndSwapLong(obj, offset, expect, update);
}
说明:它实际上是通过CAS函数操作。如果类的long对象的值是expect,则设置它的值为update。



