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 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><a href="package-summary.html#weakCompareAndSet">May fail
147 * spuriously and does not provide ordering guarantees</a>, so is
148 * only rarely an appropriate 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.compareAndSetObject(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.compareAndSetObject(obj, offset, expect, update);
450 }
451
452 public final void set(T obj, V newValue) {
453 accessCheck(obj);
454 valueCheck(newValue);
455 U.putObjectVolatile(obj, offset, newValue);
456 }
457
458 public final void lazySet(T obj, V newValue) {
459 accessCheck(obj);
460 valueCheck(newValue);
461 U.putObjectRelease(obj, offset, newValue);
462 }
463
464 @SuppressWarnings("unchecked")
465 public final V get(T obj) {
466 accessCheck(obj);
467 return (V)U.getObjectVolatile(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.getAndSetObject(obj, offset, newValue);
475 }
476 }
477 }
478