熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Web編程 >> 正文

Java多線程系列--“JUC原子類”05之 AtomicLongFieldUpdater原子類

2022-06-13   來源: Web編程 

  AtomicLongFieldUpdater介紹和函數列表

  AtomicLongFieldUpdater可以對指定"類的 &#;volatile long&#;類型的成員"進行原子更新它是基於反射原理實現的

  AtomicLongFieldUpdater函數列表

  // 受保護的無操作構造方法供子類使用 protected AtomicLongFieldUpdater() // 以原子方式將給定值添加到此更新器管理的給定對象的字段的當前值 long addAndGet(T obj long delta) // 如果當前值 == 預期值則以原子方式將此更新器所管理的給定對象的字段設置為給定的更新值 abstract boolean compareAndSet(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示例

  // LongTestjava的源碼 import ncurrentatomicAtomicLongFieldUpdater; public class LongFieldTest { public static void main(String[] args) { // 獲取Person的class對象 Class cls = Personclass; // 新建AtomicLongFieldUpdater對象傳遞參數是class對象long類型在類中對應的名稱 AtomicLongFieldUpdater mAtoLong = AtomicLongFieldUpdaternewUpdater(cls id); Person person = new Person(L); // 比較person的id屬性如果id的值為L則設置為 pareAndSet(person L ); Systemoutprintln(id=+persongetId()); } } class Person { volatile long id; public Person(long id) { thisid = id; } public void setId(long id) { thisid = 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 ncurrentatomic; import javalangreflect*; import sunmiscUnsafe; import sunreflectCallerSensitive; import sunreflectReflection; /** * A reflectionbased 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 = * AtomicReferenceFieldUpdaternewUpdater(Nodeclass Nodeclass left); * private static AtomicReferenceFieldUpdater<Node Node> rightUpdater = * AtomicReferenceFieldUpdaternewUpdater(Nodeclass Nodeclass right); * * Node getLeft() { return left; } * boolean compareAndSetLeft(Node expect Node update) { * return pareAndSet(this expect update); * } * // and so on * }}</pre> * * <p>Note that the guarantees of the {@code compareAndSet} * 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 compareAndSet} 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 reflectionbased * exception if the class does not hold field or is the wrong type */ @CallerSensitive public static <U W> AtomicReferenceFieldUpdater<UW> newUpdater(Class<U> tclass Class<W> vclass String fieldName) { return new AtomicReferenceFieldUpdaterImpl<UW>(tclass vclass fieldName ReflectiongetCallerClass()); } /** * Protected donothing 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 compareAndSet} 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 compareAndSet(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 compareAndSet} 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 compareAndSet} * * @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 compareAndSet} * * @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 (compareAndSet(obj current newValue)) return current; } } private static final class AtomicReferenceFieldUpdaterImpl<TV> extends AtomicReferenceFieldUpdater<TV> { private static final Unsafe unsafe = UnsafegetUnsafe(); 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 common * cases where the class is final (in which case a simple * getClass comparison 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 = tclassgetDeclaredField(fieldName); modifiers = fieldgetModifiers(); sunreflectmiscReflectUtilensureMemberAccess( caller tclass null modifiers); sunreflectmiscReflectUtilcheckPackageAccess(tclass); fieldClass = fieldgetType(); } catch (Exception ex) { throw new RuntimeException(ex); } if (vclass != fieldClass) throw new ClassCastException(); if (!ModifierisVolatile(modifiers)) throw new IllegalArgumentException(Must be volatile type); lass = (ModifierisProtected(modifiers) && caller != tclass) ? caller : null; thistclass = tclass; if (vclass == Objectclass) thisvclass = null; else thisvclass = vclass; offset = unsafeobjectFieldOffset(field); } void targetCheck(T obj) { if (!tclassisInstance(obj)) throw new ClassCastException(); if (cclass != null) ensureProtectedAccess(obj); } void updateCheck(T obj V update) { if (!tclassisInstance(obj) || (update != null && vclass != null && !vclassisInstance(update))) throw new ClassCastException(); if (cclass != null) ensureProtectedAccess(obj); } public boolean compareAndSet(T obj V expect V update) { if (obj == null || objgetClass() != tclass || cclass != null || (update != null && vclass != null && vclass != updategetClass())) 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 || objgetClass() != tclass || cclass != null || (update != null && vclass != null && vclass != updategetClass())) updateCheck(obj update); return pareAndSwapObject(obj offset expect update); } public void set(T obj V newValue) { if (obj == null || objgetClass() != tclass || cclass != null || (newValue != null && vclass != null && vclass != newValuegetClass())) updateCheck(obj newValue); unsafeputObjectVolatile(obj offset newValue); } public void lazySet(T obj V newValue) { if (obj == null || objgetClass() != tclass || cclass != null || (newValue != null && vclass != null && vclass != newValuegetClass())) updateCheck(obj newValue); unsafeputOrderedObject(obj offset newValue); } public V get(T obj) { if (obj == null || objgetClass() != tclass || cclass != null) targetCheck(obj); return (V)unsafegetObjectVolatile(obj offset); } private void ensureProtectedAccess(T obj) { if (cclassisInstance(obj)) { return; } throw new RuntimeException( new IllegalAccessException(Class + cclassgetName() + can not access a protected member of class + tclassgetName() + using an instance of + objgetClass()getName() ) ); } } }

  下面分析LongFieldTestjava的流程

   newUpdater()
newUpdater()的源碼如下

  public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass String fieldName) { Class<?> caller = ReflectiongetCallerClass(); if (AtomicLongVM_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 compareAndSet(T obj long expect long update) {
   if (obj == null || objgetClass() != tclass || cclass != null) fullCheck(obj);
   return pareAndSwapLong(obj offset expect update);
}

  說明它實際上是通過CAS函數操作如果類的long對象的值是expect則設置它的值為update


From:http://tw.wingwit.com/Article/program/Web/201405/30983.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.