src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java

Print this page




  99                                                         vclass,
 100                                                         fieldName);
 101     }
 102 
 103     /**
 104      * Protected do-nothing constructor for use by subclasses.
 105      */
 106     protected AtomicReferenceFieldUpdater() {
 107     }
 108 
 109     /**
 110      * Atomically sets the field of the given object managed by this updater
 111      * to the given updated value if the current value {@code ==} the
 112      * expected value. This method is guaranteed to be atomic with respect to
 113      * other calls to {@code compareAndSet} and {@code set}, but not
 114      * necessarily with respect to other changes in the field.
 115      *
 116      * @param obj An object whose field to conditionally set
 117      * @param expect the expected value
 118      * @param update the new value
 119      * @return true if successful.
 120      */
 121     public abstract boolean compareAndSet(T obj, V expect, V update);
 122 
 123     /**
 124      * Atomically sets the field of the given object managed by this updater
 125      * to the given updated value if the current value {@code ==} the
 126      * expected value. This method is guaranteed to be atomic with respect to
 127      * other calls to {@code compareAndSet} and {@code set}, but not
 128      * necessarily with respect to other changes in the field.
 129      *
 130      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
 131      * and does not provide ordering guarantees, so is only rarely an
 132      * appropriate alternative to {@code compareAndSet}.
 133      *
 134      * @param obj An object whose field to conditionally set
 135      * @param expect the expected value
 136      * @param update the new value
 137      * @return true if successful.
 138      */
 139     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
 140 
 141     /**
 142      * Sets the field of the given object managed by this updater to the
 143      * given updated value. This operation is guaranteed to act as a volatile
 144      * store with respect to subsequent invocations of {@code compareAndSet}.
 145      *
 146      * @param obj An object whose field to set
 147      * @param newValue the new value
 148      */
 149     public abstract void set(T obj, V newValue);
 150 
 151     /**
 152      * Eventually sets the field of the given object managed by this
 153      * updater to the given updated value.
 154      *
 155      * @param obj An object whose field to set
 156      * @param newValue the new value
 157      * @since 1.6


 159     public abstract void lazySet(T obj, V newValue);
 160 
 161     /**
 162      * Gets the current value held in the field of the given object managed
 163      * by this updater.
 164      *
 165      * @param obj An object whose field to get
 166      * @return the current value
 167      */
 168     public abstract V get(T obj);
 169 
 170     /**
 171      * Atomically sets the field of the given object managed by this updater
 172      * to the given value and returns the old value.
 173      *
 174      * @param obj An object whose field to get and set
 175      * @param newValue the new value
 176      * @return the previous value
 177      */
 178     public V getAndSet(T obj, V newValue) {
 179         for (;;) {
 180             V current = get(obj);
 181             if (compareAndSet(obj, current, newValue))
 182                 return current;

 183         }
 184     }
 185 
 186     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
 187         extends AtomicReferenceFieldUpdater<T,V> {
 188         private static final Unsafe unsafe = Unsafe.getUnsafe();
 189         private final long offset;
 190         private final Class<T> tclass;
 191         private final Class<V> vclass;
 192         private final Class<?> cclass;
 193 
 194         /*
 195          * Internal type checks within all update methods contain
 196          * internal inlined optimizations checking for the common
 197          * cases where the class is final (in which case a simple
 198          * getClass comparison suffices) or is of type Object (in
 199          * which case no check is needed because all objects are
 200          * instances of Object). The Object case is handled simply by
 201          * setting vclass to null in constructor.  The targetCheck and
 202          * updateCheck methods are invoked when these faster
 203          * screenings fail.
 204          */


 304                  vclass != newValue.getClass()))
 305                 updateCheck(obj, newValue);
 306             unsafe.putObjectVolatile(obj, offset, newValue);
 307         }
 308 
 309         public void lazySet(T obj, V newValue) {
 310             if (obj == null || obj.getClass() != tclass || cclass != null ||
 311                 (newValue != null && vclass != null &&
 312                  vclass != newValue.getClass()))
 313                 updateCheck(obj, newValue);
 314             unsafe.putOrderedObject(obj, offset, newValue);
 315         }
 316 
 317         @SuppressWarnings("unchecked")
 318         public V get(T obj) {
 319             if (obj == null || obj.getClass() != tclass || cclass != null)
 320                 targetCheck(obj);
 321             return (V)unsafe.getObjectVolatile(obj, offset);
 322         }
 323 









 324         private void ensureProtectedAccess(T obj) {
 325             if (cclass.isInstance(obj)) {
 326                 return;
 327             }
 328             throw new RuntimeException(
 329                 new IllegalAccessException("Class " +
 330                     cclass.getName() +
 331                     " can not access a protected member of class " +
 332                     tclass.getName() +
 333                     " using an instance of " +
 334                     obj.getClass().getName()
 335                 )
 336             );
 337         }
 338     }
 339 }


  99                                                         vclass,
 100                                                         fieldName);
 101     }
 102 
 103     /**
 104      * Protected do-nothing constructor for use by subclasses.
 105      */
 106     protected AtomicReferenceFieldUpdater() {
 107     }
 108 
 109     /**
 110      * Atomically sets the field of the given object managed by this updater
 111      * to the given updated value if the current value {@code ==} the
 112      * expected value. This method is guaranteed to be atomic with respect to
 113      * other calls to {@code compareAndSet} and {@code set}, but not
 114      * necessarily with respect to other changes in the field.
 115      *
 116      * @param obj An object whose field to conditionally set
 117      * @param expect the expected value
 118      * @param update the new value
 119      * @return true if successful
 120      */
 121     public abstract boolean compareAndSet(T obj, V expect, V update);
 122 
 123     /**
 124      * Atomically sets the field of the given object managed by this updater
 125      * to the given updated value if the current value {@code ==} the
 126      * expected value. This method is guaranteed to be atomic with respect to
 127      * other calls to {@code compareAndSet} and {@code set}, but not
 128      * necessarily with respect to other changes in the field.
 129      *
 130      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
 131      * and does not provide ordering guarantees, so is only rarely an
 132      * appropriate alternative to {@code compareAndSet}.
 133      *
 134      * @param obj An object whose field to conditionally set
 135      * @param expect the expected value
 136      * @param update the new value
 137      * @return true if successful
 138      */
 139     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
 140 
 141     /**
 142      * Sets the field of the given object managed by this updater to the
 143      * given updated value. This operation is guaranteed to act as a volatile
 144      * store with respect to subsequent invocations of {@code compareAndSet}.
 145      *
 146      * @param obj An object whose field to set
 147      * @param newValue the new value
 148      */
 149     public abstract void set(T obj, V newValue);
 150 
 151     /**
 152      * Eventually sets the field of the given object managed by this
 153      * updater to the given updated value.
 154      *
 155      * @param obj An object whose field to set
 156      * @param newValue the new value
 157      * @since 1.6


 159     public abstract void lazySet(T obj, V newValue);
 160 
 161     /**
 162      * Gets the current value held in the field of the given object managed
 163      * by this updater.
 164      *
 165      * @param obj An object whose field to get
 166      * @return the current value
 167      */
 168     public abstract V get(T obj);
 169 
 170     /**
 171      * Atomically sets the field of the given object managed by this updater
 172      * to the given value and returns the old value.
 173      *
 174      * @param obj An object whose field to get and set
 175      * @param newValue the new value
 176      * @return the previous value
 177      */
 178     public V getAndSet(T obj, V newValue) {
 179         V prev;
 180         do {
 181             prev = get(obj);
 182         } while (!compareAndSet(obj, prev, newValue));
 183         return prev;
 184     }

 185 
 186     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
 187         extends AtomicReferenceFieldUpdater<T,V> {
 188         private static final Unsafe unsafe = Unsafe.getUnsafe();
 189         private final long offset;
 190         private final Class<T> tclass;
 191         private final Class<V> vclass;
 192         private final Class<?> cclass;
 193 
 194         /*
 195          * Internal type checks within all update methods contain
 196          * internal inlined optimizations checking for the common
 197          * cases where the class is final (in which case a simple
 198          * getClass comparison suffices) or is of type Object (in
 199          * which case no check is needed because all objects are
 200          * instances of Object). The Object case is handled simply by
 201          * setting vclass to null in constructor.  The targetCheck and
 202          * updateCheck methods are invoked when these faster
 203          * screenings fail.
 204          */


 304                  vclass != newValue.getClass()))
 305                 updateCheck(obj, newValue);
 306             unsafe.putObjectVolatile(obj, offset, newValue);
 307         }
 308 
 309         public void lazySet(T obj, V newValue) {
 310             if (obj == null || obj.getClass() != tclass || cclass != null ||
 311                 (newValue != null && vclass != null &&
 312                  vclass != newValue.getClass()))
 313                 updateCheck(obj, newValue);
 314             unsafe.putOrderedObject(obj, offset, newValue);
 315         }
 316 
 317         @SuppressWarnings("unchecked")
 318         public V get(T obj) {
 319             if (obj == null || obj.getClass() != tclass || cclass != null)
 320                 targetCheck(obj);
 321             return (V)unsafe.getObjectVolatile(obj, offset);
 322         }
 323 
 324         @SuppressWarnings("unchecked")
 325         public V getAndSet(T obj, V newValue) {
 326             if (obj == null || obj.getClass() != tclass || cclass != null ||
 327                 (newValue != null && vclass != null &&
 328                  vclass != newValue.getClass()))
 329                 updateCheck(obj, newValue);
 330             return (V)unsafe.getAndSetObject(obj, offset, newValue);
 331         }
 332 
 333         private void ensureProtectedAccess(T obj) {
 334             if (cclass.isInstance(obj)) {
 335                 return;
 336             }
 337             throw new RuntimeException(
 338                 new IllegalAccessException("Class " +
 339                     cclass.getName() +
 340                     " can not access a protected member of class " +
 341                     tclass.getName() +
 342                     " using an instance of " +
 343                     obj.getClass().getName()
 344                 )
 345             );
 346         }
 347     }
 348 }