001: /*
002: * Written by Doug Lea with assistance from members of JCP JSR-166
003: * Expert Group and released to the public domain, as explained at
004: * http://creativecommons.org/licenses/publicdomain
005: */
006:
007: package java.util.concurrent.atomic;
008:
009: import sun.misc.Unsafe;
010:
011: /**
012: * An object reference that may be updated atomically. See the {@link
013: * java.util.concurrent.atomic} package specification for description
014: * of the properties of atomic variables.
015: * @since 1.5
016: * @author Doug Lea
017: * @param <V> The type of object referred to by this reference
018: */
019: public class AtomicReference<V> implements java.io.Serializable {
020: private static final long serialVersionUID = -1848883965231344442L;
021:
022: private static final Unsafe unsafe = Unsafe.getUnsafe();
023: private static final long valueOffset;
024:
025: static {
026: try {
027: valueOffset = unsafe
028: .objectFieldOffset(AtomicReference.class
029: .getDeclaredField("value"));
030: } catch (Exception ex) {
031: throw new Error(ex);
032: }
033: }
034:
035: private volatile V value;
036:
037: /**
038: * Create a new AtomicReference with the given initial value.
039: *
040: * @param initialValue the initial value
041: */
042: public AtomicReference(V initialValue) {
043: value = initialValue;
044: }
045:
046: /**
047: * Create a new AtomicReference with null initial value.
048: */
049: public AtomicReference() {
050: }
051:
052: /**
053: * Get the current value.
054: *
055: * @return the current value
056: */
057: public final V get() {
058: return value;
059: }
060:
061: /**
062: * Set to the given value.
063: *
064: * @param newValue the new value
065: */
066: public final void set(V newValue) {
067: value = newValue;
068: }
069:
070: /**
071: * Atomically set the value to the given updated value
072: * if the current value <tt>==</tt> the expected value.
073: * @param expect the expected value
074: * @param update the new value
075: * @return true if successful. False return indicates that
076: * the actual value was not equal to the expected value.
077: */
078: public final boolean compareAndSet(V expect, V update) {
079: return unsafe.compareAndSwapObject(this , valueOffset, expect,
080: update);
081: }
082:
083: /**
084: * Atomically set the value to the given updated value
085: * if the current value <tt>==</tt> the expected value.
086: * May fail spuriously.
087: * @param expect the expected value
088: * @param update the new value
089: * @return true if successful.
090: */
091: public final boolean weakCompareAndSet(V expect, V update) {
092: return unsafe.compareAndSwapObject(this , valueOffset, expect,
093: update);
094: }
095:
096: /**
097: * Set to the given value and return the old value.
098: *
099: * @param newValue the new value
100: * @return the previous value
101: */
102: public final V getAndSet(V newValue) {
103: while (true) {
104: V x = get();
105: if (compareAndSet(x, newValue))
106: return x;
107: }
108: }
109:
110: /**
111: * Returns the String representation of the current value.
112: * @return the String representation of the current value.
113: */
114: public String toString() {
115: return String.valueOf(get());
116: }
117:
118: }
|