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