如何使用AtomicBoolean以及该类的用途?


当前回答

为什么可以使用原子布尔值有两个主要原因。首先,它是可变的,例如,您可以将它作为引用传递进来,并更改与布尔值本身相关的值。

public final class MyThreadSafeClass{

    private AtomicBoolean myBoolean = new AtomicBoolean(false);
    private SomeThreadSafeObject someObject = new SomeThreadSafeObject();

    public boolean doSomething(){
         someObject.doSomeWork(myBoolean);
         return myBoolean.get(); //will return true
    }
}

和someObject类

public final class SomeThreadSafeObject{
    public void doSomeWork(AtomicBoolean b){
        b.set(true);
    }
}

更重要的是,它是线程安全的,并且可以向维护该类的开发人员表明,该变量预计将从多个线程中修改和读取。如果不使用AtomicBoolean,则必须通过将布尔变量声明为volatile或围绕字段的读写同步来同步所使用的布尔变量。

其他回答

这是我做的笔记(摘自Brian Goetz的书),可能对你有帮助

原子XXX类

provide Non-blocking Compare-And-Swap implementation Takes advantage of the support provide by hardware (the CMPXCHG instruction on Intel) When lots of threads are running through your code that uses these atomic concurrency API, they will scale much better than code which uses Object level monitors/synchronization. Since, Java's synchronization mechanisms makes code wait, when there are lots of threads running through your critical sections, a substantial amount of CPU time is spent in managing the synchronization mechanism itself (waiting, notifying, etc). Since the new API uses hardware level constructs (atomic variables) and wait and lock free algorithms to implement thread-safety, a lot more of CPU time is spent "doing stuff" rather than in managing synchronization. not only offer better throughput, but they also provide greater resistance to liveness problems such as deadlock and priority inversion.

当多个线程需要检查和更改布尔值时。例如:

if (!initialized) {
   initialize();
   initialized = true;
}

这不是线程安全的。你可以使用AtomicBoolean来修复它:

if (atomicInitialized.compareAndSet(false, true)) {
    initialize();
}

节选自包装描述

Package java.util.concurrent.atomic description: A small toolkit of classes that support lock-free thread-safe programming on single variables.[...] The specifications of these methods enable implementations to employ efficient machine-level atomic instructions that are available on contemporary processors.[...] Instances of classes AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference each provide access and updates to a single variable of the corresponding type.[...] The memory effects for accesses and updates of atomics generally follow the rules for volatiles: get has the memory effects of reading a volatile variable. set has the memory effects of writing (assigning) a volatile variable. weakCompareAndSet atomically reads and conditionally writes a variable, is ordered with respect to other memory operations on that variable, but otherwise acts as an ordinary non-volatile memory operation. compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.

AtomicBoolean类为您提供了一个可以自动更新的布尔值。当有多个线程访问一个布尔变量时使用它。

atomic包概述为您提供了一个很好的高级描述,说明这个包中的类做什么以及何时使用它们。我还推荐Brian Goetz写的《Java并发实践》这本书。

为什么可以使用原子布尔值有两个主要原因。首先,它是可变的,例如,您可以将它作为引用传递进来,并更改与布尔值本身相关的值。

public final class MyThreadSafeClass{

    private AtomicBoolean myBoolean = new AtomicBoolean(false);
    private SomeThreadSafeObject someObject = new SomeThreadSafeObject();

    public boolean doSomething(){
         someObject.doSomeWork(myBoolean);
         return myBoolean.get(); //will return true
    }
}

和someObject类

public final class SomeThreadSafeObject{
    public void doSomeWork(AtomicBoolean b){
        b.set(true);
    }
}

更重要的是,它是线程安全的,并且可以向维护该类的开发人员表明,该变量预计将从多个线程中修改和读取。如果不使用AtomicBoolean,则必须通过将布尔变量声明为volatile或围绕字段的读写同步来同步所使用的布尔变量。