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.Objects; 44 import java.util.function.BinaryOperator; 45 import java.util.function.UnaryOperator; 46 import jdk.internal.misc.Unsafe; 47 import jdk.internal.reflect.CallerSensitive; 48 import jdk.internal.reflect.Reflection; 49 import java.lang.invoke.VarHandle; 50 51 /** 52 * A reflection-based utility that enables atomic updates to 53 * designated {@code volatile} reference fields of designated 54 * classes. This class is designed for use in atomic data structures 55 * in which several reference fields of the same node are 56 * independently subject to atomic updates. For example, a tree node 57 * might be declared as 58 * 59 * <pre> {@code 60 * class Node { 61 * private volatile Node left, right; 62 * 63 * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater = 64 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left"); 65 * private static final AtomicReferenceFieldUpdater<Node, Node> rightUpdater = 66 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); 67 * 68 * Node getLeft() { return left; } 69 * boolean compareAndSetLeft(Node expect, Node update) { 70 * return leftUpdater.compareAndSet(this, expect, update); 71 * } 72 * // ... and so on 73 * }}</pre> 74 * 75 * <p>Note that the guarantees of the {@code compareAndSet} 76 * method in this class are weaker than in other atomic classes. 77 * Because this class cannot ensure that all uses of the field 78 * are appropriate for purposes of atomic access, it can 79 * guarantee atomicity only with respect to other invocations of 80 * {@code compareAndSet} and {@code set} on the same updater. 81 * 82 * <p>Object arguments for parameters of type {@code T} that are not 83 * instances of the class passed to {@link #newUpdater} will result in 84 * a {@link ClassCastException} being thrown. 85 * 86 * @since 1.5 87 * @author Doug Lea 88 * @param <T> The type of the object holding the updatable field 89 * @param <V> The type of the field 90 */ 91 public abstract class AtomicReferenceFieldUpdater<T,V> { 92 93 /** 94 * Creates and returns an updater for objects with the given field. 95 * The Class arguments are needed to check that reflective types and 96 * generic types match. 97 * 98 * @param tclass the class of the objects holding the field 99 * @param vclass the class of the field 100 * @param fieldName the name of the field to be updated 101 * @param <U> the type of instances of tclass 102 * @param <W> the type of instances of vclass 103 * @return the updater 104 * @throws ClassCastException if the field is of the wrong type 105 * @throws IllegalArgumentException if the field is not volatile 106 * @throws RuntimeException with a nested reflection-based 107 * exception if the class does not hold field or is the wrong type, 108 * or the field is inaccessible to the caller according to Java language 109 * access control 110 */ 111 @CallerSensitive 112 public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, 113 Class<W> vclass, 114 String fieldName) { 115 return new AtomicReferenceFieldUpdaterImpl<U,W> 116 (tclass, vclass, fieldName, Reflection.getCallerClass()); 117 } 118 119 /** 120 * Protected do-nothing constructor for use by subclasses. 121 */ 122 protected AtomicReferenceFieldUpdater() { 123 } 124 125 /** 126 * Atomically sets the field of the given object managed by this updater 127 * to the given updated value if the current value {@code ==} the 128 * expected value. This method is guaranteed to be atomic with respect to 129 * other calls to {@code compareAndSet} and {@code set}, but not 130 * necessarily with respect to other changes in the field. 131 * 132 * @param obj An object whose field to conditionally set 133 * @param expect the expected value 134 * @param update the new value 135 * @return {@code true} if successful 136 */ 137 public abstract boolean compareAndSet(T obj, V expect, V update); 138 139 /** 140 * Atomically sets the field of the given object managed by this updater 141 * to the given updated value if the current value {@code ==} the 142 * expected value. This method is guaranteed to be atomic with respect to 143 * other calls to {@code compareAndSet} and {@code set}, but not 144 * necessarily with respect to other changes in the field. 145 * 146 * <p>This operation may fail spuriously and does not provide 147 * ordering guarantees, so is only rarely an appropriate 148 * alternative to {@code compareAndSet}. 149 * 150 * @param obj An object whose field to conditionally set 151 * @param expect the expected value 152 * @param update the new value 153 * @return {@code true} if successful 154 */ 155 public abstract boolean weakCompareAndSet(T obj, V expect, V update); 156 157 /** 158 * Sets the field of the given object managed by this updater to the 159 * given updated value. This operation is guaranteed to act as a volatile 160 * store with respect to subsequent invocations of {@code compareAndSet}. 161 * 162 * @param obj An object whose field to set 163 * @param newValue the new value 164 */ 165 public abstract void set(T obj, V newValue); 166 167 /** 168 * Eventually sets the field of the given object managed by this 169 * updater to the given updated value. 170 * 171 * @param obj An object whose field to set 172 * @param newValue the new value 173 * @since 1.6 174 */ 175 public abstract void lazySet(T obj, V newValue); 176 177 /** 178 * Returns the current value held in the field of the given object 179 * managed by this updater. 180 * 181 * @param obj An object whose field to get 182 * @return the current value 183 */ 184 public abstract V get(T obj); 185 186 /** 187 * Atomically sets the field of the given object managed by this updater 188 * to the given value and returns the old value. 189 * 190 * @param obj An object whose field to get and set 191 * @param newValue the new value 192 * @return the previous value 193 */ 194 public V getAndSet(T obj, V newValue) { 195 V prev; 196 do { 197 prev = get(obj); 198 } while (!compareAndSet(obj, prev, newValue)); 199 return prev; 200 } 201 202 /** 203 * Atomically updates (with memory effects as specified by {@link 204 * VarHandle#compareAndSet}) the field of the given object managed 205 * by this updater with the results of applying the given 206 * function, returning the previous value. The function should be 207 * side-effect-free, since it may be re-applied when attempted 208 * updates fail due to contention among threads. 209 * 210 * @param obj An object whose field to get and set 211 * @param updateFunction a side-effect-free function 212 * @return the previous value 213 * @since 1.8 214 */ 215 public final V getAndUpdate(T obj, UnaryOperator<V> updateFunction) { 216 V prev, next; 217 do { 218 prev = get(obj); 219 next = updateFunction.apply(prev); 220 } while (!compareAndSet(obj, prev, next)); 221 return prev; 222 } 223 224 /** 225 * Atomically updates (with memory effects as specified by {@link 226 * VarHandle#compareAndSet}) the field of the given object managed 227 * by this updater with the results of applying the given 228 * function, returning the updated value. The function should be 229 * side-effect-free, since it may be re-applied when attempted 230 * updates fail due to contention among threads. 231 * 232 * @param obj An object whose field to get and set 233 * @param updateFunction a side-effect-free function 234 * @return the updated value 235 * @since 1.8 236 */ 237 public final V updateAndGet(T obj, UnaryOperator<V> updateFunction) { 238 V prev, next; 239 do { 240 prev = get(obj); 241 next = updateFunction.apply(prev); 242 } while (!compareAndSet(obj, prev, next)); 243 return next; 244 } 245 246 /** 247 * Atomically updates (with memory effects as specified by {@link 248 * VarHandle#compareAndSet}) the field of the given object managed 249 * by this updater with the results of applying the given function 250 * to the current and given values, returning the previous value. 251 * The function should be side-effect-free, since it may be 252 * re-applied when attempted updates fail due to contention among 253 * threads. The function is applied with the current value as its 254 * first argument, and the given update as the second argument. 255 * 256 * @param obj An object whose field to get and set 257 * @param x the update value 258 * @param accumulatorFunction a side-effect-free function of two arguments 259 * @return the previous value 260 * @since 1.8 261 */ 262 public final V getAndAccumulate(T obj, V x, 263 BinaryOperator<V> accumulatorFunction) { 264 V prev, next; 265 do { 266 prev = get(obj); 267 next = accumulatorFunction.apply(prev, x); 268 } while (!compareAndSet(obj, prev, next)); 269 return prev; 270 } 271 272 /** 273 * Atomically updates (with memory effects as specified by {@link 274 * VarHandle#compareAndSet}) the field of the given object managed 275 * by this updater with the results of applying the given function 276 * to the current and given values, returning the updated value. 277 * The function should be side-effect-free, since it may be 278 * re-applied when attempted updates fail due to contention among 279 * threads. The function is applied with the current value as its 280 * first argument, and the given update as the second argument. 281 * 282 * @param obj An object whose field to get and set 283 * @param x the update value 284 * @param accumulatorFunction a side-effect-free function of two arguments 285 * @return the updated value 286 * @since 1.8 287 */ 288 public final V accumulateAndGet(T obj, V x, 289 BinaryOperator<V> accumulatorFunction) { 290 V prev, next; 291 do { 292 prev = get(obj); 293 next = accumulatorFunction.apply(prev, x); 294 } while (!compareAndSet(obj, prev, next)); 295 return next; 296 } 297 298 private static final class AtomicReferenceFieldUpdaterImpl<T,V> 299 extends AtomicReferenceFieldUpdater<T,V> { 300 private static final Unsafe U = Unsafe.getUnsafe(); 301 private final long offset; 302 /** 303 * if field is protected, the subclass constructing updater, else 304 * the same as tclass 305 */ 306 private final Class<?> cclass; 307 /** class holding the field */ 308 private final Class<T> tclass; 309 /** field value type */ 310 private final Class<V> vclass; 311 312 /* 313 * Internal type checks within all update methods contain 314 * internal inlined optimizations checking for the common 315 * cases where the class is final (in which case a simple 316 * getClass comparison suffices) or is of type Object (in 317 * which case no check is needed because all objects are 318 * instances of Object). The Object case is handled simply by 319 * setting vclass to null in constructor. The targetCheck and 320 * updateCheck methods are invoked when these faster 321 * screenings fail. 322 */ 323 324 AtomicReferenceFieldUpdaterImpl(final Class<T> tclass, 325 final Class<V> vclass, 326 final String fieldName, 327 final Class<?> caller) { 328 final Field field; 329 final Class<?> fieldClass; 330 final int modifiers; 331 try { 332 field = AccessController.doPrivileged( 333 new PrivilegedExceptionAction<Field>() { 334 public Field run() throws NoSuchFieldException { 335 return tclass.getDeclaredField(fieldName); 336 } 337 }); 338 modifiers = field.getModifiers(); 339 sun.reflect.misc.ReflectUtil.ensureMemberAccess( 340 caller, tclass, null, modifiers); 341 ClassLoader cl = tclass.getClassLoader(); 342 ClassLoader ccl = caller.getClassLoader(); 343 if ((ccl != null) && (ccl != cl) && 344 ((cl == null) || !isAncestor(cl, ccl))) { 345 sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); 346 } 347 fieldClass = field.getType(); 348 } catch (PrivilegedActionException pae) { 349 throw new RuntimeException(pae.getException()); 350 } catch (Exception ex) { 351 throw new RuntimeException(ex); 352 } 353 354 if (vclass != fieldClass) 355 throw new ClassCastException(); 356 if (vclass.isPrimitive()) 357 throw new IllegalArgumentException("Must be reference type"); 358 359 if (!Modifier.isVolatile(modifiers)) 360 throw new IllegalArgumentException("Must be volatile type"); 361 362 // Access to protected field members is restricted to receivers only 363 // of the accessing class, or one of its subclasses, and the 364 // accessing class must in turn be a subclass (or package sibling) 365 // of the protected member's defining class. 366 // If the updater refers to a protected field of a declaring class 367 // outside the current package, the receiver argument will be 368 // narrowed to the type of the accessing class. 369 this.cclass = (Modifier.isProtected(modifiers) && 370 tclass.isAssignableFrom(caller) && 371 !isSamePackage(tclass, caller)) 372 ? caller : tclass; 373 this.tclass = tclass; 374 this.vclass = vclass; 375 this.offset = U.objectFieldOffset(field); 376 } 377 378 /** 379 * Returns true if the second classloader can be found in the first 380 * classloader's delegation chain. 381 * Equivalent to the inaccessible: first.isAncestor(second). 382 */ 383 private static boolean isAncestor(ClassLoader first, ClassLoader second) { 384 ClassLoader acl = first; 385 do { 386 acl = acl.getParent(); 387 if (second == acl) { 388 return true; 389 } 390 } while (acl != null); 391 return false; 392 } 393 394 /** 395 * Returns true if the two classes have the same class loader and 396 * package qualifier 397 */ 398 private static boolean isSamePackage(Class<?> class1, Class<?> class2) { 399 return class1.getClassLoader() == class2.getClassLoader() 400 && Objects.equals(class1.getPackageName(), class2.getPackageName()); 401 } 402 403 /** 404 * Checks that target argument is instance of cclass. On 405 * failure, throws cause. 406 */ 407 private final void accessCheck(T obj) { 408 if (!cclass.isInstance(obj)) 409 throwAccessCheckException(obj); 410 } 411 412 /** 413 * Throws access exception if accessCheck failed due to 414 * protected access, else ClassCastException. 415 */ 416 private final void throwAccessCheckException(T obj) { 417 if (cclass == tclass) 418 throw new ClassCastException(); 419 else 420 throw new RuntimeException( 421 new IllegalAccessException( 422 "Class " + 423 cclass.getName() + 424 " can not access a protected member of class " + 425 tclass.getName() + 426 " using an instance of " + 427 obj.getClass().getName())); 428 } 429 430 private final void valueCheck(V v) { 431 if (v != null && !(vclass.isInstance(v))) 432 throwCCE(); 433 } 434 435 static void throwCCE() { 436 throw new ClassCastException(); 437 } 438 439 public final boolean compareAndSet(T obj, V expect, V update) { 440 accessCheck(obj); 441 valueCheck(update); 442 return U.compareAndSetReference(obj, offset, expect, update); 443 } 444 445 public final boolean weakCompareAndSet(T obj, V expect, V update) { 446 // same implementation as strong form for now 447 accessCheck(obj); 448 valueCheck(update); 449 return U.compareAndSetReference(obj, offset, expect, update); 450 } 451 452 public final void set(T obj, V newValue) { 453 accessCheck(obj); 454 valueCheck(newValue); 455 U.putReferenceVolatile(obj, offset, newValue); 456 } 457 458 public final void lazySet(T obj, V newValue) { 459 accessCheck(obj); 460 valueCheck(newValue); 461 U.putReferenceRelease(obj, offset, newValue); 462 } 463 464 @SuppressWarnings("unchecked") 465 public final V get(T obj) { 466 accessCheck(obj); 467 return (V)U.getReferenceVolatile(obj, offset); 468 } 469 470 @SuppressWarnings("unchecked") 471 public final V getAndSet(T obj, V newValue) { 472 accessCheck(obj); 473 valueCheck(newValue); 474 return (V)U.getAndSetReference(obj, offset, newValue); 475 } 476 } 477 }