知识大全 Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类

Posted

篇首语:若要功夫深,铁杵磨成针。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类相关的知识,希望对你有一定的参考价值。

Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  AtomicLongFieldUpdater介绍和函数列表

  AtomicLongFieldUpdater可以对指定"类的 &# ;volatile long&# ;类型的成员"进行原子更新 它是基于反射原理实现的

  AtomicLongFieldUpdater函数列表

  // 受保护的无操作构造方法 供子类使用 protected AtomicLongFieldUpdater() // 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值 long addAndGet(T obj long delta) // 如果当前值 == 预期值 则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值 abstract boolean pareAndSet(T obj long expect long update) // 以原子方式将此更新器管理的给定对象字段当前值减 long decrementAndGet(T obj) // 获取此更新器管理的在给定对象的字段中保持的当前值 abstract long get(T obj) // 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值 long getAndAdd(T obj long delta) // 以原子方式将此更新器管理的给定对象字段当前值减 long getAndDecrement(T obj) // 以原子方式将此更新器管理的给定对象字段的当前值加 long getAndIncrement(T obj) // 将此更新器管理的给定对象的字段以原子方式设置为给定值 并返回旧值 long getAndSet(T obj long newValue) // 以原子方式将此更新器管理的给定对象字段当前值加 long incrementAndGet(T obj) // 最后将此更新器管理的给定对象的字段设置为给定更新值 abstract void lazySet(T obj long newValue) // 为对象创建并返回一个具有给定字段的更新器 static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass String fieldName) // 将此更新器管理的给定对象的字段设置为给定更新值 abstract void set(T obj long newValue) // 如果当前值 == 预期值 则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值 abstract boolean weakCompareAndSet(T obj long expect long update)

  AtomicLongFieldUpdater示例

  // LongTest java的源码 import ncurrent 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( L); // 比较person的 id 属性 如果id的值为 L 则设置为 pareAndSet(person L ); 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=

  AtomicLongFieldUpdater源码分析(基于JDK _ )

  AtomicLongFieldUpdater完整源码

  /* * ORACLE PROPRIETARY/CONFIDENTIAL Use is subject to license terms * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * Written by Doug Lea with assistance from members of JCP JSR * Expert Group and released to the public domain as explained at * */ package ncurrent atomic; import java lang reflect *; import sun misc Unsafe; import sun reflect CallerSensitive; import sun reflect Reflection; /** * A reflection based utility that enables atomic updates to * designated @code volatile reference fields of designated * classes This class is designed for use in atomic data structures * in which several reference fields of the same node are * independently subject to atomic updates For example a tree node * might be declared as * * <pre> @code * class Node * private volatile Node left right; * * private static final AtomicReferenceFieldUpdater<Node Node> leftUpdater = * AtomicReferenceFieldUpdater newUpdater(Node class Node class left ); * private static AtomicReferenceFieldUpdater<Node Node> rightUpdater = * AtomicReferenceFieldUpdater newUpdater(Node class Node class right ); * * Node getLeft() return left; * boolean pareAndSetLeft(Node expect Node update) * return pareAndSet(this expect update); * * // and so on * </pre> * * <p>Note that the guarantees of the @code pareAndSet * method in this class are weaker than in other atomic classes * Because this class cannot ensure that all uses of the field * are appropriate for purposes of atomic access it can * guarantee atomicity only with respect to other invocations of * @code pareAndSet and @code set on the same updater * * @since * @author Doug Lea * @param <T> The type of the object holding the updatable field * @param <V> The type of the field */ public abstract class AtomicReferenceFieldUpdater<T V> /** * Creates and returns an updater for objects with the given field * The Class arguments are needed to check that reflective types and * generic types match * * @param tclass the class of the objects holding the field * @param vclass the class of the field * @param fieldName the name of the field to be updated * @return the updater * @throws IllegalArgumentException if the field is not a volatile reference type * @throws RuntimeException with a nested reflection based * exception if the class does not hold field or is the wrong type */ @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()); /** * Protected do nothing constructor for use by subclasses */ protected AtomicReferenceFieldUpdater() /** * Atomically sets the field of the given object managed by this updater * to the given updated value if the current value @code == the * expected value This method is guaranteed to be atomic with respect to * other calls to @code pareAndSet and @code set but not * necessarily with respect to other changes in the field * * @param obj An object whose field to conditionally set * @param expect the expected value * @param update the new value * @return true if successful */ public abstract boolean pareAndSet(T obj V expect V update); /** * Atomically sets the field of the given object managed by this updater * to the given updated value if the current value @code == the * expected value This method is guaranteed to be atomic with respect to * other calls to @code pareAndSet and @code set but not * necessarily with respect to other changes in the field * * <p>May <a href= l#Spurious >fail spuriously</a> * and does not provide ordering guarantees so is only rarely an * appropriate alternative to @code pareAndSet * * @param obj An object whose field to conditionally set * @param expect the expected value * @param update the new value * @return true if successful */ public abstract boolean weakCompareAndSet(T obj V expect V update); /** * Sets the field of the given object managed by this updater to the * given updated value This operation is guaranteed to act as a volatile * store with respect to subsequent invocations of @code pareAndSet * * @param obj An object whose field to set * @param newValue the new value */ public abstract void set(T obj V newValue); /** * Eventually sets the field of the given object managed by this * updater to the given updated value * * @param obj An object whose field to set * @param newValue the new value * @since */ public abstract void lazySet(T obj V newValue); /** * Gets the current value held in the field of the given object managed * by this updater * * @param obj An object whose field to get * @return the current value */ public abstract V get(T obj); /** * Atomically sets the field of the given object managed by this updater * to the given value and returns the old value * * @param obj An object whose field to get and set * @param newValue the new value * @return the previous value */ public V getAndSet(T obj V newValue) for (;;) V current = get(obj); if (pareAndSet(obj current newValue)) return current; private static final class AtomicReferenceFieldUpdaterImpl<T V> extends AtomicReferenceFieldUpdater<T V> private static final Unsafe unsafe = Unsafe getUnsafe(); private final long offset; private final Class<T> tclass; private final Class<V> vclass; private final Class cclass; /* * Internal type checks within all update methods contain * internal inlined optimizations checking for the mon * cases where the class is final (in which case a simple * getClass parison suffices) or is of type Object (in * which case no check is needed because all objects are * instances of Object) The Object case is handled simply by * setting vclass to null in constructor The targetCheck and * updateCheck methods are invoked when these faster * screenings fail */ AtomicReferenceFieldUpdaterImpl(Class<T> tclass Class<V> vclass String fieldName Class<?> caller) Field field = null; Class fieldClass = null; int modifiers = ; 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 ); lass = (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 pareAndSet(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 pareAndSwapObject(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 pareAndSwapObject(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的流程

   newUpdater()newUpdater()的源码如下

  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);

  说明 newUpdater()的作用是获取一个AtomicIntegerFieldUpdater类型的对象 它实际上返回的是CASUpdater对象 或者LockedUpdater对象 具体返回哪一个类取决于JVM是否支持long类型的CAS函数 CASUpdater和LockedUpdater都是AtomicIntegerFieldUpdater的子类 它们的实现类似 下面以CASUpdater来进行说明

  CASUpdater类的源码如下

  public boolean pareAndSet(T obj long expect long update)    if (obj == null || obj getClass() != tclass || cclass != null) fullCheck(obj);    return pareAndSwapLong(obj offset expect update);

cha138/Article/program/Web/201405/30983

相关参考

知识大全 Java多线程编程基础之线程对象

Java多线程编程基础之线程对象  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nbs

知识大全 Java多线程开发之线程局部变量的使用

Java多线程开发之线程局部变量的使用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &

知识大全 实战Java多线程编程精要之高级支持

实战Java多线程编程精要之高级支持  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  线程组  线

知识大全 Java多线程之ConcurrentHashMap深入分析

Java多线程之ConcurrentHashMap深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 Java多线程之volatile深入分析

Java多线程之volatile深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  vola

知识大全 Java多线程(五)之BlockingQueue深入分析

Java多线程(五)之BlockingQueue深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 Java多线程问题之同步器CyclicBarrier

Java多线程问题之同步器CyclicBarrier  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 实战体会Java多线程编程精要之基础

实战体会Java多线程编程精要之基础  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n

知识大全 实战Java多线程编程精要之限制优先级

实战Java多线程编程精要之限制优先级  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  限制线程优

知识大全 Java多线程编程之不提倡的方法

Java多线程编程之不提倡的方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 不提倡使用的方法是