Home | History | Annotate | Download | only in atomic
      1 /*
      2  * Written by Doug Lea with assistance from members of JCP JSR-166
      3  * Expert Group and released to the public domain, as explained at
      4  * http://creativecommons.org/publicdomain/zero/1.0/
      5  */
      6 
      7 package java.util.concurrent.atomic;
      8 import sun.misc.Unsafe;
      9 
     10 /**
     11  * A {@code boolean} value that may be updated atomically. See the
     12  * {@link java.util.concurrent.atomic} package specification for
     13  * description of the properties of atomic variables. An
     14  * {@code AtomicBoolean} is used in applications such as atomically
     15  * updated flags, and cannot be used as a replacement for a
     16  * {@link java.lang.Boolean}.
     17  *
     18  * @since 1.5
     19  * @author Doug Lea
     20  */
     21 public class AtomicBoolean implements java.io.Serializable {
     22     private static final long serialVersionUID = 4654671469794556979L;
     23     // setup to use Unsafe.compareAndSwapInt for updates
     24     private static final Unsafe unsafe = Unsafe.getUnsafe();
     25     private static final long valueOffset;
     26 
     27     static {
     28         try {
     29             valueOffset = unsafe.objectFieldOffset
     30                 (AtomicBoolean.class.getDeclaredField("value"));
     31         } catch (Exception ex) { throw new Error(ex); }
     32     }
     33 
     34     private volatile int value;
     35 
     36     /**
     37      * Creates a new {@code AtomicBoolean} with the given initial value.
     38      *
     39      * @param initialValue the initial value
     40      */
     41     public AtomicBoolean(boolean initialValue) {
     42         value = initialValue ? 1 : 0;
     43     }
     44 
     45     /**
     46      * Creates a new {@code AtomicBoolean} with initial value {@code false}.
     47      */
     48     public AtomicBoolean() {
     49     }
     50 
     51     /**
     52      * Returns the current value.
     53      *
     54      * @return the current value
     55      */
     56     public final boolean get() {
     57         return value != 0;
     58     }
     59 
     60     /**
     61      * Atomically sets the value to the given updated value
     62      * if the current value {@code ==} the expected value.
     63      *
     64      * @param expect the expected value
     65      * @param update the new value
     66      * @return true if successful. False return indicates that
     67      * the actual value was not equal to the expected value.
     68      */
     69     public final boolean compareAndSet(boolean expect, boolean update) {
     70         int e = expect ? 1 : 0;
     71         int u = update ? 1 : 0;
     72         return unsafe.compareAndSwapInt(this, valueOffset, e, u);
     73     }
     74 
     75     /**
     76      * Atomically sets the value to the given updated value
     77      * if the current value {@code ==} the expected value.
     78      *
     79      * <p><a href="package-summary.html#weakCompareAndSet">May fail
     80      * spuriously and does not provide ordering guarantees</a>, so is
     81      * only rarely an appropriate alternative to {@code compareAndSet}.
     82      *
     83      * @param expect the expected value
     84      * @param update the new value
     85      * @return true if successful
     86      */
     87     public boolean weakCompareAndSet(boolean expect, boolean update) {
     88         int e = expect ? 1 : 0;
     89         int u = update ? 1 : 0;
     90         return unsafe.compareAndSwapInt(this, valueOffset, e, u);
     91     }
     92 
     93     /**
     94      * Unconditionally sets to the given value.
     95      *
     96      * @param newValue the new value
     97      */
     98     public final void set(boolean newValue) {
     99         value = newValue ? 1 : 0;
    100     }
    101 
    102     /**
    103      * Eventually sets to the given value.
    104      *
    105      * @param newValue the new value
    106      * @since 1.6
    107      */
    108     public final void lazySet(boolean newValue) {
    109         int v = newValue ? 1 : 0;
    110         unsafe.putOrderedInt(this, valueOffset, v);
    111     }
    112 
    113     /**
    114      * Atomically sets to the given value and returns the previous value.
    115      *
    116      * @param newValue the new value
    117      * @return the previous value
    118      */
    119     public final boolean getAndSet(boolean newValue) {
    120         for (;;) {
    121             boolean current = get();
    122             if (compareAndSet(current, newValue))
    123                 return current;
    124         }
    125     }
    126 
    127     /**
    128      * Returns the String representation of the current value.
    129      * @return the String representation of the current value
    130      */
    131     public String toString() {
    132         return Boolean.toString(get());
    133     }
    134 
    135 }
    136