001: /*
002: * Written by Doug Lea with assistance from members of JCP JSR-166
003: * Expert Group and released to the public domain, as explained at
004: * http://creativecommons.org/licenses/publicdomain
005: */
006:
007: package java.util.concurrent.atomic;
008:
009: import sun.misc.Unsafe;
010:
011: /**
012: * A <tt>boolean</tt> value that may be updated atomically. See the
013: * {@link java.util.concurrent.atomic} package specification for
014: * description of the properties of atomic variables. An
015: * <tt>AtomicBoolean</tt> is used in applications such as atomically
016: * updated flags, and cannot be used as a replacement for a
017: * {@link java.lang.Boolean}.
018: *
019: * @since 1.5
020: * @author Doug Lea
021: */
022: public class AtomicBoolean implements java.io.Serializable {
023: private static final long serialVersionUID = 4654671469794556979L;
024: // setup to use Unsafe.compareAndSwapInt for updates
025: private static final Unsafe unsafe = Unsafe.getUnsafe();
026: private static final long valueOffset;
027:
028: static {
029: try {
030: valueOffset = unsafe.objectFieldOffset(AtomicBoolean.class
031: .getDeclaredField("value"));
032: } catch (Exception ex) {
033: throw new Error(ex);
034: }
035: }
036:
037: private volatile int value;
038:
039: /**
040: * Creates a new <tt>AtomicBoolean</tt> with the given initial value.
041: *
042: * @param initialValue the initial value
043: */
044: public AtomicBoolean(boolean initialValue) {
045: value = initialValue ? 1 : 0;
046: }
047:
048: /**
049: * Creates a new <tt>AtomicBoolean</tt> with initial value <tt>false</tt>.
050: */
051: public AtomicBoolean() {
052: }
053:
054: /**
055: * Returns the current value.
056: *
057: * @return the current value
058: */
059: public final boolean get() {
060: return value != 0;
061: }
062:
063: /**
064: * Atomically sets the value to the given update value if the
065: * current value is equal to the expected value. Any given
066: * invocation of this operation may fail (return
067: * <tt>false</tt>) spuriously, but repeated invocation when
068: * the current value holds the expected value and no other thread
069: * is also attempting to set the value will eventually succeed.
070: *
071: * @param expect the expected value
072: * @param update the new value
073: * @return true if successful
074: */
075: public final boolean compareAndSet(boolean expect, boolean update) {
076: int e = expect ? 1 : 0;
077: int u = update ? 1 : 0;
078: return unsafe.compareAndSwapInt(this , valueOffset, e, u);
079: }
080:
081: /**
082: * Atomically set the value to the given updated value
083: * if the current value <tt>==</tt> the expected value.
084: * May fail spuriously.
085: * @param expect the expected value
086: * @param update the new value
087: * @return true if successful.
088: */
089: public boolean weakCompareAndSet(boolean expect, boolean update) {
090: int e = expect ? 1 : 0;
091: int u = update ? 1 : 0;
092: return unsafe.compareAndSwapInt(this , valueOffset, e, u);
093: }
094:
095: /**
096: * Unconditionally sets to the given value.
097: *
098: * @param newValue the new value
099: */
100: public final void set(boolean newValue) {
101: value = newValue ? 1 : 0;
102: }
103:
104: /**
105: * Sets to the given value and returns the previous value.
106: *
107: * @param newValue the new value
108: * @return the previous value
109: */
110: public final boolean getAndSet(boolean newValue) {
111: for (;;) {
112: boolean current = get();
113: if (compareAndSet(current, newValue))
114: return current;
115: }
116: }
117:
118: /**
119: * Returns the String representation of the current value.
120: * @return the String representation of the current value.
121: */
122: public String toString() {
123: return Boolean.toString(get());
124: }
125:
126: }
|