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/licenses/publicdomain
34 */
35
36 package java.util.concurrent.atomic;
37 import sun.misc.Unsafe;
38 import java.lang.reflect.*;
39
40 /**
41 * A reflection-based utility that enables atomic updates to
42 * designated {@code volatile} reference fields of designated
43 * classes. This class is designed for use in atomic data structures
44 * in which several reference fields of the same node are
45 * independently subject to atomic updates. For example, a tree node
46 * might be declared as
47 *
48 * <pre>
49 * class Node {
50 * private volatile Node left, right;
51 *
52 * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
53 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
54 * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
55 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
56 *
57 * Node getLeft() { return left; }
58 * boolean compareAndSetLeft(Node expect, Node update) {
59 * return leftUpdater.compareAndSet(this, expect, update);
60 * }
61 * // ... and so on
62 * }
63 * </pre>
64 *
65 * <p>Note that the guarantees of the {@code compareAndSet}
66 * method in this class are weaker than in other atomic classes.
67 * Because this class cannot ensure that all uses of the field
68 * are appropriate for purposes of atomic access, it can
69 * guarantee atomicity only with respect to other invocations of
70 * {@code compareAndSet} and {@code set} on the same updater.
71 *
72 * @since 1.5
73 * @author Doug Lea
74 * @param <T> The type of the object holding the updatable field
75 * @param <V> The type of the field
76 */
77 public abstract class AtomicReferenceFieldUpdater<T, V> {
78
79 /**
80 * Creates and returns an updater for objects with the given field.
81 * The Class arguments are needed to check that reflective types and
82 * generic types match.
83 *
274 }
275
276 public void lazySet(T obj, V newValue) {
277 if (obj == null || obj.getClass() != tclass || cclass != null ||
278 (newValue != null && vclass != null &&
279 vclass != newValue.getClass()))
280 updateCheck(obj, newValue);
281 unsafe.putOrderedObject(obj, offset, newValue);
282 }
283
284 public V get(T obj) {
285 if (obj == null || obj.getClass() != tclass || cclass != null)
286 targetCheck(obj);
287 return (V)unsafe.getObjectVolatile(obj, offset);
288 }
289
290 private void ensureProtectedAccess(T obj) {
291 if (cclass.isInstance(obj)) {
292 return;
293 }
294 throw new RuntimeException (
295 new IllegalAccessException("Class " +
296 cclass.getName() +
297 " can not access a protected member of class " +
298 tclass.getName() +
299 " using an instance of " +
300 obj.getClass().getName()
301 )
302 );
303 }
304 }
305 }
|
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/licenses/publicdomain
34 */
35
36 package java.util.concurrent.atomic;
37 import sun.misc.Unsafe;
38 import java.lang.reflect.*;
39
40 /**
41 * A reflection-based utility that enables atomic updates to
42 * designated {@code volatile} reference fields of designated
43 * classes. This class is designed for use in atomic data structures
44 * in which several reference fields of the same node are
45 * independently subject to atomic updates. For example, a tree node
46 * might be declared as
47 *
48 * <pre> {@code
49 * class Node {
50 * private volatile Node left, right;
51 *
52 * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
53 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
54 * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
55 * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
56 *
57 * Node getLeft() { return left; }
58 * boolean compareAndSetLeft(Node expect, Node update) {
59 * return leftUpdater.compareAndSet(this, expect, update);
60 * }
61 * // ... and so on
62 * }}</pre>
63 *
64 * <p>Note that the guarantees of the {@code compareAndSet}
65 * method in this class are weaker than in other atomic classes.
66 * Because this class cannot ensure that all uses of the field
67 * are appropriate for purposes of atomic access, it can
68 * guarantee atomicity only with respect to other invocations of
69 * {@code compareAndSet} and {@code set} on the same updater.
70 *
71 * @since 1.5
72 * @author Doug Lea
73 * @param <T> The type of the object holding the updatable field
74 * @param <V> The type of the field
75 */
76 public abstract class AtomicReferenceFieldUpdater<T, V> {
77
78 /**
79 * Creates and returns an updater for objects with the given field.
80 * The Class arguments are needed to check that reflective types and
81 * generic types match.
82 *
273 }
274
275 public void lazySet(T obj, V newValue) {
276 if (obj == null || obj.getClass() != tclass || cclass != null ||
277 (newValue != null && vclass != null &&
278 vclass != newValue.getClass()))
279 updateCheck(obj, newValue);
280 unsafe.putOrderedObject(obj, offset, newValue);
281 }
282
283 public V get(T obj) {
284 if (obj == null || obj.getClass() != tclass || cclass != null)
285 targetCheck(obj);
286 return (V)unsafe.getObjectVolatile(obj, offset);
287 }
288
289 private void ensureProtectedAccess(T obj) {
290 if (cclass.isInstance(obj)) {
291 return;
292 }
293 throw new RuntimeException(
294 new IllegalAccessException("Class " +
295 cclass.getName() +
296 " can not access a protected member of class " +
297 tclass.getName() +
298 " using an instance of " +
299 obj.getClass().getName()
300 )
301 );
302 }
303 }
304 }
|