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 }