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 * A {@code boolean} value that may be updated atomically. See the
042 * {@link java.util.concurrent.atomic} package specification for
043 * description of the properties of atomic variables. An
044 * {@code AtomicBoolean} is used in applications such as atomically
045 * updated flags, and cannot be used as a replacement for a
046 * {@link java.lang.Boolean}.
047 *
048 * @since 1.5
049 * @author Doug Lea
050 */
051 public class AtomicBoolean implements java.io.Serializable {
052 private static final long serialVersionUID = 4654671469794556979L;
053 // setup to use Unsafe.compareAndSwapInt for updates
054 private static final Unsafe unsafe = Unsafe.getUnsafe();
055 private static final long valueOffset;
056
057 static {
058 try {
059 valueOffset = unsafe.objectFieldOffset(AtomicBoolean.class
060 .getDeclaredField("value"));
061 } catch (Exception ex) {
062 throw new Error(ex);
063 }
064 }
065
066 private volatile int value;
067
068 /**
069 * Creates a new {@code AtomicBoolean} with the given initial value.
070 *
071 * @param initialValue the initial value
072 */
073 public AtomicBoolean(boolean initialValue) {
074 value = initialValue ? 1 : 0;
075 }
076
077 /**
078 * Creates a new {@code AtomicBoolean} with initial value {@code false}.
079 */
080 public AtomicBoolean() {
081 }
082
083 /**
084 * Returns the current value.
085 *
086 * @return the current value
087 */
088 public final boolean get() {
089 return value != 0;
090 }
091
092 /**
093 * Atomically sets the value to the given updated value
094 * if the current value {@code ==} the expected value.
095 *
096 * @param expect the expected value
097 * @param update the new value
098 * @return true if successful. False return indicates that
099 * the actual value was not equal to the expected value.
100 */
101 public final boolean compareAndSet(boolean expect, boolean update) {
102 int e = expect ? 1 : 0;
103 int u = update ? 1 : 0;
104 return unsafe.compareAndSwapInt(this , valueOffset, e, u);
105 }
106
107 /**
108 * Atomically sets the value to the given updated value
109 * if the current value {@code ==} the expected value.
110 *
111 * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
112 * and does not provide ordering guarantees, so is only rarely an
113 * appropriate alternative to {@code compareAndSet}.
114 *
115 * @param expect the expected value
116 * @param update the new value
117 * @return true if successful.
118 */
119 public boolean weakCompareAndSet(boolean expect, boolean update) {
120 int e = expect ? 1 : 0;
121 int u = update ? 1 : 0;
122 return unsafe.compareAndSwapInt(this , valueOffset, e, u);
123 }
124
125 /**
126 * Unconditionally sets to the given value.
127 *
128 * @param newValue the new value
129 */
130 public final void set(boolean newValue) {
131 value = newValue ? 1 : 0;
132 }
133
134 /**
135 * Eventually sets to the given value.
136 *
137 * @param newValue the new value
138 * @since 1.6
139 */
140 public final void lazySet(boolean newValue) {
141 int v = newValue ? 1 : 0;
142 unsafe.putOrderedInt(this , valueOffset, v);
143 }
144
145 /**
146 * Atomically sets to the given value and returns the previous value.
147 *
148 * @param newValue the new value
149 * @return the previous value
150 */
151 public final boolean getAndSet(boolean newValue) {
152 for (;;) {
153 boolean current = get();
154 if (compareAndSet(current, newValue))
155 return current;
156 }
157 }
158
159 /**
160 * Returns the String representation of the current value.
161 * @return the String representation of the current value.
162 */
163 public String toString() {
164 return Boolean.toString(get());
165 }
166
167 }
|