栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java concurrency之AtomicLongFieldUpdater原子类_动力节点Java学院整理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java concurrency之AtomicLongFieldUpdater原子类_动力节点Java学院整理

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。 

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号