1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent.atomic; 37 38 import java.lang.invoke.MethodHandles; 39 import java.lang.invoke.VarHandle; 40 41 /** 42 * A {@code boolean} value that may be updated atomically. See the 43 * {@link VarHandle} specification for descriptions of the properties 44 * of atomic accesses. An {@code AtomicBoolean} is used in 45 * applications such as atomically updated flags, and cannot be used 46 * as a replacement for a {@link java.lang.Boolean}. 47 * 48 * @since 1.5 49 * @author Doug Lea 50 */ 51 public class AtomicBoolean implements java.io.Serializable { 52 private static final long serialVersionUID = 4654671469794556979L; 53 private static final VarHandle VALUE; 54 static { 55 try { 56 MethodHandles.Lookup l = MethodHandles.lookup(); 57 VALUE = l.findVarHandle(AtomicBoolean.class, "value", int.class); 58 } catch (ReflectiveOperationException e) { 59 throw new ExceptionInInitializerError(e); 60 } 61 } 62 63 private volatile int value; 64 65 /** 66 * Creates a new {@code AtomicBoolean} with the given initial value. 67 * 68 * @param initialValue the initial value 69 */ 70 public AtomicBoolean(boolean initialValue) { 71 value = initialValue ? 1 : 0; 72 } 73 74 /** 75 * Creates a new {@code AtomicBoolean} with initial value {@code false}. 76 */ 77 public AtomicBoolean() { 78 } 79 80 /** 81 * Returns the current value, 82 * with memory effects as specified by {@link VarHandle#getVolatile}. 83 * 84 * @return the current value 85 */ 86 public final boolean get() { 87 return value != 0; 88 } 89 90 /** 91 * Atomically sets the value to {@code newValue} 92 * if the current value {@code == expectedValue}, 93 * with memory effects as specified by {@link VarHandle#compareAndSet}. 94 * 95 * @param expectedValue the expected value 96 * @param newValue the new value 97 * @return {@code true} if successful. False return indicates that 98 * the actual value was not equal to the expected value. 99 */ 100 public final boolean compareAndSet(boolean expectedValue, boolean newValue) { 101 return VALUE.compareAndSet(this, 102 (expectedValue ? 1 : 0), 103 (newValue ? 1 : 0)); 104 } 105 106 /** 107 * Possibly atomically sets the value to {@code newValue} 108 * if the current value {@code == expectedValue}, 109 * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}. 110 * 111 * @deprecated This method has plain memory effects but the method 112 * name implies volatile memory effects (see methods such as 113 * {@link #compareAndExchange} and {@link #compareAndSet}). To avoid 114 * confusion over plain or volatile memory effects it is recommended that 115 * the method {@link #weakCompareAndSetPlain} be used instead. 116 * 117 * @param expectedValue the expected value 118 * @param newValue the new value 119 * @return {@code true} if successful 120 * @see #weakCompareAndSetPlain 121 */ 122 @Deprecated(since="9") 123 public boolean weakCompareAndSet(boolean expectedValue, boolean newValue) { 124 return VALUE.weakCompareAndSetPlain(this, 125 (expectedValue ? 1 : 0), 126 (newValue ? 1 : 0)); 127 } 128 129 /** 130 * Possibly atomically sets the value to {@code newValue} 131 * if the current value {@code == expectedValue}, 132 * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}. 133 * 134 * @param expectedValue the expected value 135 * @param newValue the new value 136 * @return {@code true} if successful 137 * @since 9 138 */ 139 public boolean weakCompareAndSetPlain(boolean expectedValue, boolean newValue) { 140 return VALUE.weakCompareAndSetPlain(this, 141 (expectedValue ? 1 : 0), 142 (newValue ? 1 : 0)); 143 } 144 145 /** 146 * Sets the value to {@code newValue}, 147 * with memory effects as specified by {@link VarHandle#setVolatile}. 148 * 149 * @param newValue the new value 150 */ 151 public final void set(boolean newValue) { 152 value = newValue ? 1 : 0; 153 } 154 155 /** 156 * Sets the value to {@code newValue}, 157 * with memory effects as specified by {@link VarHandle#setRelease}. 158 * 159 * @param newValue the new value 160 * @since 1.6 161 */ 162 public final void lazySet(boolean newValue) { 163 VALUE.setRelease(this, (newValue ? 1 : 0)); 164 } 165 166 /** 167 * Atomically sets the value to {@code newValue} and returns the old value, 168 * with memory effects as specified by {@link VarHandle#getAndSet}. 169 * 170 * @param newValue the new value 171 * @return the previous value 172 */ 173 public final boolean getAndSet(boolean newValue) { 174 return (int)VALUE.getAndSet(this, (newValue ? 1 : 0)) != 0; 175 } 176 177 /** 178 * Returns the String representation of the current value. 179 * @return the String representation of the current value 180 */ 181 public String toString() { 182 return Boolean.toString(get()); 183 } 184 185 // jdk9 186 187 /** 188 * Returns the current value, with memory semantics of reading as 189 * if the variable was declared non-{@code volatile}. 190 * 191 * @return the value 192 * @since 9 193 */ 194 public final boolean getPlain() { 195 return (int)VALUE.get(this) != 0; 196 } 197 198 /** 199 * Sets the value to {@code newValue}, with memory semantics 200 * of setting as if the variable was declared non-{@code volatile} 201 * and non-{@code final}. 202 * 203 * @param newValue the new value 204 * @since 9 205 */ 206 public final void setPlain(boolean newValue) { 207 VALUE.set(this, newValue ? 1 : 0); 208 } 209 210 /** 211 * Returns the current value, 212 * with memory effects as specified by {@link VarHandle#getOpaque}. 213 * 214 * @return the value 215 * @since 9 216 */ 217 public final boolean getOpaque() { 218 return (int)VALUE.getOpaque(this) != 0; 219 } 220 221 /** 222 * Sets the value to {@code newValue}, 223 * with memory effects as specified by {@link VarHandle#setOpaque}. 224 * 225 * @param newValue the new value 226 * @since 9 227 */ 228 public final void setOpaque(boolean newValue) { 229 VALUE.setOpaque(this, newValue ? 1 : 0); 230 } 231 232 /** 233 * Returns the current value, 234 * with memory effects as specified by {@link VarHandle#getAcquire}. 235 * 236 * @return the value 237 * @since 9 238 */ 239 public final boolean getAcquire() { 240 return (int)VALUE.getAcquire(this) != 0; 241 } 242 243 /** 244 * Sets the value to {@code newValue}, 245 * with memory effects as specified by {@link VarHandle#setRelease}. 246 * 247 * @param newValue the new value 248 * @since 9 249 */ 250 public final void setRelease(boolean newValue) { 251 VALUE.setRelease(this, newValue ? 1 : 0); 252 } 253 254 /** 255 * Atomically sets the value to {@code newValue} if the current value, 256 * referred to as the <em>witness value</em>, {@code == expectedValue}, 257 * with memory effects as specified by 258 * {@link VarHandle#compareAndExchange}. 259 * 260 * @param expectedValue the expected value 261 * @param newValue the new value 262 * @return the witness value, which will be the same as the 263 * expected value if successful 264 * @since 9 265 */ 266 public final boolean compareAndExchange(boolean expectedValue, boolean newValue) { 267 return (int)VALUE.compareAndExchange(this, 268 (expectedValue ? 1 : 0), 269 (newValue ? 1 : 0)) != 0; 270 } 271 272 /** 273 * Atomically sets the value to {@code newValue} if the current value, 274 * referred to as the <em>witness value</em>, {@code == expectedValue}, 275 * with memory effects as specified by 276 * {@link VarHandle#compareAndExchangeAcquire}. 277 * 278 * @param expectedValue the expected value 279 * @param newValue the new value 280 * @return the witness value, which will be the same as the 281 * expected value if successful 282 * @since 9 283 */ 284 public final boolean compareAndExchangeAcquire(boolean expectedValue, boolean newValue) { 285 return (int)VALUE.compareAndExchangeAcquire(this, 286 (expectedValue ? 1 : 0), 287 (newValue ? 1 : 0)) != 0; 288 } 289 290 /** 291 * Atomically sets the value to {@code newValue} if the current value, 292 * referred to as the <em>witness value</em>, {@code == expectedValue}, 293 * with memory effects as specified by 294 * {@link VarHandle#compareAndExchangeRelease}. 295 * 296 * @param expectedValue the expected value 297 * @param newValue the new value 298 * @return the witness value, which will be the same as the 299 * expected value if successful 300 * @since 9 301 */ 302 public final boolean compareAndExchangeRelease(boolean expectedValue, boolean newValue) { 303 return (int)VALUE.compareAndExchangeRelease(this, 304 (expectedValue ? 1 : 0), 305 (newValue ? 1 : 0)) != 0; 306 } 307 308 /** 309 * Possibly atomically sets the value to {@code newValue} if the current 310 * value {@code == expectedValue}, 311 * with memory effects as specified by 312 * {@link VarHandle#weakCompareAndSet}. 313 * 314 * @param expectedValue the expected value 315 * @param newValue the new value 316 * @return {@code true} if successful 317 * @since 9 318 */ 319 public final boolean weakCompareAndSetVolatile(boolean expectedValue, boolean newValue) { 320 return VALUE.weakCompareAndSet(this, 321 (expectedValue ? 1 : 0), 322 (newValue ? 1 : 0)); 323 } 324 325 /** 326 * Possibly atomically sets the value to {@code newValue} if the current 327 * value {@code == expectedValue}, 328 * with memory effects as specified by 329 * {@link VarHandle#weakCompareAndSetAcquire}. 330 * 331 * @param expectedValue the expected value 332 * @param newValue the new value 333 * @return {@code true} if successful 334 * @since 9 335 */ 336 public final boolean weakCompareAndSetAcquire(boolean expectedValue, boolean newValue) { 337 return VALUE.weakCompareAndSetAcquire(this, 338 (expectedValue ? 1 : 0), 339 (newValue ? 1 : 0)); 340 } 341 342 /** 343 * Possibly atomically sets the value to {@code newValue} if the current 344 * value {@code == expectedValue}, 345 * with memory effects as specified by 346 * {@link VarHandle#weakCompareAndSetRelease}. 347 * 348 * @param expectedValue the expected value 349 * @param newValue the new value 350 * @return {@code true} if successful 351 * @since 9 352 */ 353 public final boolean weakCompareAndSetRelease(boolean expectedValue, boolean newValue) { 354 return VALUE.weakCompareAndSetRelease(this, 355 (expectedValue ? 1 : 0), 356 (newValue ? 1 : 0)); 357 } 358 359 }