001 /*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
003 *
004 * This code is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU General Public License version 2 only, as
006 * published by the Free Software Foundation. Sun designates this
007 * particular file as subject to the "Classpath" exception as provided
008 * by Sun in the LICENSE file that accompanied this code.
009 *
010 * This code is distributed in the hope that it will be useful, but WITHOUT
011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
013 * version 2 for more details (a copy is included in the LICENSE file that
014 * accompanied this code).
015 *
016 * You should have received a copy of the GNU General Public License version
017 * 2 along with this work; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
019 *
020 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
021 * CA 95054 USA or visit www.sun.com if you need additional information or
022 * have any questions.
023 */
024
025 /*
026 * This file is available under and governed by the GNU General Public
027 * License version 2 only, as published by the Free Software Foundation.
028 * However, the following notice accompanied the original version of this
029 * file:
030 *
031 * Written by Doug Lea with assistance from members of JCP JSR-166
032 * Expert Group and released to the public domain, as explained at
033 * http://creativecommons.org/licenses/publicdomain
034 */
035
036 package java.util.concurrent.atomic;
037
038 import sun.misc.Unsafe;
039
040 /**
041 * An object reference that may be updated atomically. See the {@link
042 * java.util.concurrent.atomic} package specification for description
043 * of the properties of atomic variables.
044 * @since 1.5
045 * @author Doug Lea
046 * @param <V> The type of object referred to by this reference
047 */
048 public class AtomicReference<V> implements java.io.Serializable {
049 private static final long serialVersionUID = -1848883965231344442L;
050
051 private static final Unsafe unsafe = Unsafe.getUnsafe();
052 private static final long valueOffset;
053
054 static {
055 try {
056 valueOffset = unsafe
057 .objectFieldOffset(AtomicReference.class
058 .getDeclaredField("value"));
059 } catch (Exception ex) {
060 throw new Error(ex);
061 }
062 }
063
064 private volatile V value;
065
066 /**
067 * Creates a new AtomicReference with the given initial value.
068 *
069 * @param initialValue the initial value
070 */
071 public AtomicReference(V initialValue) {
072 value = initialValue;
073 }
074
075 /**
076 * Creates a new AtomicReference with null initial value.
077 */
078 public AtomicReference() {
079 }
080
081 /**
082 * Gets the current value.
083 *
084 * @return the current value
085 */
086 public final V get() {
087 return value;
088 }
089
090 /**
091 * Sets to the given value.
092 *
093 * @param newValue the new value
094 */
095 public final void set(V newValue) {
096 value = newValue;
097 }
098
099 /**
100 * Eventually sets to the given value.
101 *
102 * @param newValue the new value
103 * @since 1.6
104 */
105 public final void lazySet(V newValue) {
106 unsafe.putOrderedObject(this , valueOffset, newValue);
107 }
108
109 /**
110 * Atomically sets the value to the given updated value
111 * if the current value {@code ==} the expected value.
112 * @param expect the expected value
113 * @param update the new value
114 * @return true if successful. False return indicates that
115 * the actual value was not equal to the expected value.
116 */
117 public final boolean compareAndSet(V expect, V update) {
118 return unsafe.compareAndSwapObject(this , valueOffset, expect,
119 update);
120 }
121
122 /**
123 * Atomically sets the value to the given updated value
124 * if the current value {@code ==} the expected value.
125 *
126 * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
127 * and does not provide ordering guarantees, so is only rarely an
128 * appropriate alternative to {@code compareAndSet}.
129 *
130 * @param expect the expected value
131 * @param update the new value
132 * @return true if successful.
133 */
134 public final boolean weakCompareAndSet(V expect, V update) {
135 return unsafe.compareAndSwapObject(this , valueOffset, expect,
136 update);
137 }
138
139 /**
140 * Atomically sets to the given value and returns the old value.
141 *
142 * @param newValue the new value
143 * @return the previous value
144 */
145 public final V getAndSet(V newValue) {
146 while (true) {
147 V x = get();
148 if (compareAndSet(x, newValue))
149 return x;
150 }
151 }
152
153 /**
154 * Returns the String representation of the current value.
155 * @return the String representation of the current value.
156 */
157 public String toString() {
158 return String.valueOf(get());
159 }
160
161 }
|