1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent.atomic; 37 38 import java.lang.reflect.Field; 39 import java.lang.reflect.Modifier; 40 import java.security.AccessController; 41 import java.security.PrivilegedActionException; 42 import java.security.PrivilegedExceptionAction; 43 import java.util.function.BinaryOperator; 44 import java.util.function.UnaryOperator; 45 import sun.reflect.CallerSensitive; 46 import sun.reflect.Reflection; 47 48 /** 49 * A reflection-based utility that enables atomic updates to 50 * designated {@code volatile} reference fields of designated 51 * classes. This class is designed for use in atomic data structures 52 * in which several reference fields of the same node are 53 * independently subject to atomic updates. For example, a tree node 54 * might be declared as 55 * 56 * <pre> {@code 57 * class Node { 58 * private volatile Node left, right; 59 * 60 * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater = 61 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left"); 62 * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater = 63 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); 64 * 65 * Node getLeft() { return left; } 66 * boolean compareAndSetLeft(Node expect, Node update) { 67 * return leftUpdater.compareAndSet(this, expect, update); 68 * } 69 * // ... and so on 70 * }}</pre> 71 * 72 * <p>Note that the guarantees of the {@code compareAndSet} 73 * method in this class are weaker than in other atomic classes. 74 * Because this class cannot ensure that all uses of the field 75 * are appropriate for purposes of atomic access, it can 76 * guarantee atomicity only with respect to other invocations of 77 * {@code compareAndSet} and {@code set} on the same updater. 78 * 79 * @since 1.5 80 * @author Doug Lea 81 * @param <T> The type of the object holding the updatable field 82 * @param <V> The type of the field 83 */ 84 public abstract class AtomicReferenceFieldUpdater<T,V> { 85 86 /** 87 * Creates and returns an updater for objects with the given field. 88 * The Class arguments are needed to check that reflective types and 89 * generic types match. 90 * 91 * @param tclass the class of the objects holding the field 92 * @param vclass the class of the field 93 * @param fieldName the name of the field to be updated 94 * @param <U> the type of instances of tclass 95 * @param <W> the type of instances of vclass 96 * @return the updater 97 * @throws ClassCastException if the field is of the wrong type 98 * @throws IllegalArgumentException if the field is not volatile 99 * @throws RuntimeException with a nested reflection-based 100 * exception if the class does not hold field or is the wrong type, 101 * or the field is inaccessible to the caller according to Java language 102 * access control 103 */ 104 @CallerSensitive newUpdater(Class<U> tclass, Class<W> vclass, String fieldName)105 public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, 106 Class<W> vclass, 107 String fieldName) { 108 return new AtomicReferenceFieldUpdaterImpl<U,W> 109 (tclass, vclass, fieldName, Reflection.getCallerClass()); 110 } 111 112 /** 113 * Protected do-nothing constructor for use by subclasses. 114 */ AtomicReferenceFieldUpdater()115 protected AtomicReferenceFieldUpdater() { 116 } 117 118 /** 119 * Atomically sets the field of the given object managed by this updater 120 * to the given updated value if the current value {@code ==} the 121 * expected value. This method is guaranteed to be atomic with respect to 122 * other calls to {@code compareAndSet} and {@code set}, but not 123 * necessarily with respect to other changes in the field. 124 * 125 * @param obj An object whose field to conditionally set 126 * @param expect the expected value 127 * @param update the new value 128 * @return {@code true} if successful 129 */ compareAndSet(T obj, V expect, V update)130 public abstract boolean compareAndSet(T obj, V expect, V update); 131 132 /** 133 * Atomically sets the field of the given object managed by this updater 134 * to the given updated value if the current value {@code ==} the 135 * expected value. This method is guaranteed to be atomic with respect to 136 * other calls to {@code compareAndSet} and {@code set}, but not 137 * necessarily with respect to other changes in the field. 138 * 139 * <p><a href="package-summary.html#weakCompareAndSet">May fail 140 * spuriously and does not provide ordering guarantees</a>, so is 141 * only rarely an appropriate alternative to {@code compareAndSet}. 142 * 143 * @param obj An object whose field to conditionally set 144 * @param expect the expected value 145 * @param update the new value 146 * @return {@code true} if successful 147 */ weakCompareAndSet(T obj, V expect, V update)148 public abstract boolean weakCompareAndSet(T obj, V expect, V update); 149 150 /** 151 * Sets the field of the given object managed by this updater to the 152 * given updated value. This operation is guaranteed to act as a volatile 153 * store with respect to subsequent invocations of {@code compareAndSet}. 154 * 155 * @param obj An object whose field to set 156 * @param newValue the new value 157 */ set(T obj, V newValue)158 public abstract void set(T obj, V newValue); 159 160 /** 161 * Eventually sets the field of the given object managed by this 162 * updater to the given updated value. 163 * 164 * @param obj An object whose field to set 165 * @param newValue the new value 166 * @since 1.6 167 */ lazySet(T obj, V newValue)168 public abstract void lazySet(T obj, V newValue); 169 170 /** 171 * Gets the current value held in the field of the given object managed 172 * by this updater. 173 * 174 * @param obj An object whose field to get 175 * @return the current value 176 */ get(T obj)177 public abstract V get(T obj); 178 179 /** 180 * Atomically sets the field of the given object managed by this updater 181 * to the given value and returns the old value. 182 * 183 * @param obj An object whose field to get and set 184 * @param newValue the new value 185 * @return the previous value 186 */ getAndSet(T obj, V newValue)187 public V getAndSet(T obj, V newValue) { 188 V prev; 189 do { 190 prev = get(obj); 191 } while (!compareAndSet(obj, prev, newValue)); 192 return prev; 193 } 194 195 /** 196 * Atomically updates the field of the given object managed by this updater 197 * with the results of applying the given function, returning the previous 198 * value. The function should be side-effect-free, since it may be 199 * re-applied when attempted updates fail due to contention among threads. 200 * 201 * @param obj An object whose field to get and set 202 * @param updateFunction a side-effect-free function 203 * @return the previous value 204 * @since 1.8 205 */ getAndUpdate(T obj, UnaryOperator<V> updateFunction)206 public final V getAndUpdate(T obj, UnaryOperator<V> updateFunction) { 207 V prev, next; 208 do { 209 prev = get(obj); 210 next = updateFunction.apply(prev); 211 } while (!compareAndSet(obj, prev, next)); 212 return prev; 213 } 214 215 /** 216 * Atomically updates the field of the given object managed by this updater 217 * with the results of applying the given function, returning the updated 218 * value. The function should be side-effect-free, since it may be 219 * re-applied when attempted updates fail due to contention among threads. 220 * 221 * @param obj An object whose field to get and set 222 * @param updateFunction a side-effect-free function 223 * @return the updated value 224 * @since 1.8 225 */ updateAndGet(T obj, UnaryOperator<V> updateFunction)226 public final V updateAndGet(T obj, UnaryOperator<V> updateFunction) { 227 V prev, next; 228 do { 229 prev = get(obj); 230 next = updateFunction.apply(prev); 231 } while (!compareAndSet(obj, prev, next)); 232 return next; 233 } 234 235 /** 236 * Atomically updates the field of the given object managed by this 237 * updater with the results of applying the given function to the 238 * current and given values, returning the previous value. The 239 * function should be side-effect-free, since it may be re-applied 240 * when attempted updates fail due to contention among threads. The 241 * function is applied with the current value as its first argument, 242 * and the given update as the second argument. 243 * 244 * @param obj An object whose field to get and set 245 * @param x the update value 246 * @param accumulatorFunction a side-effect-free function of two arguments 247 * @return the previous value 248 * @since 1.8 249 */ getAndAccumulate(T obj, V x, BinaryOperator<V> accumulatorFunction)250 public final V getAndAccumulate(T obj, V x, 251 BinaryOperator<V> accumulatorFunction) { 252 V prev, next; 253 do { 254 prev = get(obj); 255 next = accumulatorFunction.apply(prev, x); 256 } while (!compareAndSet(obj, prev, next)); 257 return prev; 258 } 259 260 /** 261 * Atomically updates the field of the given object managed by this 262 * updater with the results of applying the given function to the 263 * current and given values, returning the updated value. The 264 * function should be side-effect-free, since it may be re-applied 265 * when attempted updates fail due to contention among threads. The 266 * function is applied with the current value as its first argument, 267 * and the given update as the second argument. 268 * 269 * @param obj An object whose field to get and set 270 * @param x the update value 271 * @param accumulatorFunction a side-effect-free function of two arguments 272 * @return the updated value 273 * @since 1.8 274 */ accumulateAndGet(T obj, V x, BinaryOperator<V> accumulatorFunction)275 public final V accumulateAndGet(T obj, V x, 276 BinaryOperator<V> accumulatorFunction) { 277 V prev, next; 278 do { 279 prev = get(obj); 280 next = accumulatorFunction.apply(prev, x); 281 } while (!compareAndSet(obj, prev, next)); 282 return next; 283 } 284 285 private static final class AtomicReferenceFieldUpdaterImpl<T,V> 286 extends AtomicReferenceFieldUpdater<T,V> { 287 private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 288 private final long offset; 289 /** 290 * if field is protected, the subclass constructing updater, else 291 * the same as tclass 292 */ 293 private final Class<?> cclass; 294 /** class holding the field */ 295 private final Class<T> tclass; 296 /** field value type */ 297 private final Class<V> vclass; 298 299 /* 300 * Internal type checks within all update methods contain 301 * internal inlined optimizations checking for the common 302 * cases where the class is final (in which case a simple 303 * getClass comparison suffices) or is of type Object (in 304 * which case no check is needed because all objects are 305 * instances of Object). The Object case is handled simply by 306 * setting vclass to null in constructor. The targetCheck and 307 * updateCheck methods are invoked when these faster 308 * screenings fail. 309 */ 310 AtomicReferenceFieldUpdaterImpl(final Class<T> tclass, final Class<V> vclass, final String fieldName, final Class<?> caller)311 AtomicReferenceFieldUpdaterImpl(final Class<T> tclass, 312 final Class<V> vclass, 313 final String fieldName, 314 final Class<?> caller) { 315 final Field field; 316 final Class<?> fieldClass; 317 final int modifiers; 318 try { 319 // Android-changed: Skip privilege escalation which is a noop on Android. 320 /* 321 field = AccessController.doPrivileged( 322 new PrivilegedExceptionAction<Field>() { 323 public Field run() throws NoSuchFieldException { 324 return tclass.getDeclaredField(fieldName); 325 } 326 }); 327 */ 328 field = tclass.getDeclaredField(fieldName); 329 modifiers = field.getModifiers(); 330 sun.reflect.misc.ReflectUtil.ensureMemberAccess( 331 caller, tclass, null, modifiers); 332 // Android-removed: Skip checkPackageAccess which is a noop on Android. 333 /* 334 ClassLoader cl = tclass.getClassLoader(); 335 ClassLoader ccl = caller.getClassLoader(); 336 if ((ccl != null) && (ccl != cl) && 337 ((cl == null) || !isAncestor(cl, ccl))) { 338 sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); 339 } 340 */ 341 fieldClass = field.getType(); 342 // Android-removed: Skip privilege escalation which is a noop on Android. 343 /* 344 } catch (PrivilegedActionException pae) { 345 throw new RuntimeException(pae.getException()); 346 */ 347 } catch (Exception ex) { 348 throw new RuntimeException(ex); 349 } 350 351 if (vclass != fieldClass) 352 throw new ClassCastException(); 353 if (vclass.isPrimitive()) 354 throw new IllegalArgumentException("Must be reference type"); 355 356 if (!Modifier.isVolatile(modifiers)) 357 throw new IllegalArgumentException("Must be volatile type"); 358 359 this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; 360 this.tclass = tclass; 361 this.vclass = vclass; 362 this.offset = U.objectFieldOffset(field); 363 } 364 365 // Android-removed: isAncestor's only usage was removed above. 366 /* 367 /** 368 * Returns true if the second classloader can be found in the first 369 * classloader's delegation chain. 370 * Equivalent to the inaccessible: first.isAncestor(second). 371 * 372 private static boolean isAncestor(ClassLoader first, ClassLoader second) { 373 ClassLoader acl = first; 374 do { 375 acl = acl.getParent(); 376 if (second == acl) { 377 return true; 378 } 379 } while (acl != null); 380 return false; 381 } 382 */ 383 384 /** 385 * Checks that target argument is instance of cclass. On 386 * failure, throws cause. 387 */ accessCheck(T obj)388 private final void accessCheck(T obj) { 389 if (!cclass.isInstance(obj)) 390 throwAccessCheckException(obj); 391 } 392 393 /** 394 * Throws access exception if accessCheck failed due to 395 * protected access, else ClassCastException. 396 */ throwAccessCheckException(T obj)397 private final void throwAccessCheckException(T obj) { 398 if (cclass == tclass) 399 throw new ClassCastException(); 400 else 401 throw new RuntimeException( 402 new IllegalAccessException( 403 "Class " + 404 cclass.getName() + 405 " can not access a protected member of class " + 406 tclass.getName() + 407 " using an instance of " + 408 obj.getClass().getName())); 409 } 410 valueCheck(V v)411 private final void valueCheck(V v) { 412 if (v != null && !(vclass.isInstance(v))) 413 throwCCE(); 414 } 415 throwCCE()416 static void throwCCE() { 417 throw new ClassCastException(); 418 } 419 compareAndSet(T obj, V expect, V update)420 public final boolean compareAndSet(T obj, V expect, V update) { 421 accessCheck(obj); 422 valueCheck(update); 423 return U.compareAndSwapObject(obj, offset, expect, update); 424 } 425 weakCompareAndSet(T obj, V expect, V update)426 public final boolean weakCompareAndSet(T obj, V expect, V update) { 427 // same implementation as strong form for now 428 accessCheck(obj); 429 valueCheck(update); 430 return U.compareAndSwapObject(obj, offset, expect, update); 431 } 432 set(T obj, V newValue)433 public final void set(T obj, V newValue) { 434 accessCheck(obj); 435 valueCheck(newValue); 436 U.putObjectVolatile(obj, offset, newValue); 437 } 438 lazySet(T obj, V newValue)439 public final void lazySet(T obj, V newValue) { 440 accessCheck(obj); 441 valueCheck(newValue); 442 U.putOrderedObject(obj, offset, newValue); 443 } 444 445 @SuppressWarnings("unchecked") get(T obj)446 public final V get(T obj) { 447 accessCheck(obj); 448 return (V)U.getObjectVolatile(obj, offset); 449 } 450 451 @SuppressWarnings("unchecked") getAndSet(T obj, V newValue)452 public final V getAndSet(T obj, V newValue) { 453 accessCheck(obj); 454 valueCheck(newValue); 455 return (V)U.getAndSetObject(obj, offset, newValue); 456 } 457 } 458 } 459