AtomicReference.java revision a807b4d808d2591894daf13aab179b2e9c46a2f5
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent.atomic; 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport sun.misc.Unsafe; 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An object reference that may be updated atomically. See the {@link 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * java.util.concurrent.atomic} package specification for description 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the properties of atomic variables. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <V> The type of object referred to by this reference 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 18bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilsonpublic class AtomicReference<V> implements java.io.Serializable { 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -1848883965231344442L; 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 21a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private static final Unsafe unsafe = Unsafe.getUnsafe(); 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long valueOffset; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 25a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 26a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson valueOffset = unsafe.objectFieldOffset 27a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson (AtomicReference.class.getDeclaredField("value")); 28a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } catch (Exception ex) { throw new Error(ex); } 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private volatile V value; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 34bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Creates a new AtomicReference with the given initial value. 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param initialValue the initial value 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AtomicReference(V initialValue) { 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project value = initialValue; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 43bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Creates a new AtomicReference with null initial value. 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AtomicReference() { 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 47bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 49bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Gets the current value. 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the current value 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final V get() { 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return value; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 56bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 58bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Sets to the given value. 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void set(V newValue) { 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project value = newValue; 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 65bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Eventually sets to the given value. 686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param newValue the new value 706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6 716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void lazySet(V newValue) { 736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unsafe.putOrderedObject(this, valueOffset, newValue); 746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 77bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the value to the given updated value 78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * if the current value {@code ==} the expected value. 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if successful. False return indicates that 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the actual value was not equal to the expected value. 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean compareAndSet(V expect, V update) { 85bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return unsafe.compareAndSwapObject(this, valueOffset, expect, update); 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the value to the given updated value 90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * if the current value {@code ==} the expected value. 91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>May <a href="package-summary.html#Spurious">fail spuriously</a> 93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * and does not provide ordering guarantees, so is only rarely an 94bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * appropriate alternative to {@code compareAndSet}. 95bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if successful. 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean weakCompareAndSet(V expect, V update) { 101bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return unsafe.compareAndSwapObject(this, valueOffset, expect, update); 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 105bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets to the given value and returns the old value. 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final V getAndSet(V newValue) { 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project V x = get(); 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(x, newValue)) 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return x; 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the String representation of the current value. 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the String representation of the current value. 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return String.valueOf(get()); 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 127