什么时候我需要在Java中使用AtomicBoolean ?

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

198483 次浏览

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

AtomicXXX类

  • 提供非阻塞比较和交换实现

  • 利用提供的支持 由硬件(CMPXCHG指令 当大量的线程 运行使用的代码 这些原子并发API,它们 可伸缩性会比代码更好吗 它使用对象级 监控/同步。因为, Java的同步机制 使代码等待,当有很多 在你的 关键部分,一个实质性的 占用的CPU时间 管理同步 机制本身(等待,通知, 等等)。因为新的API使用硬件 关卡构造(原子变量) 并将空闲算法锁定到 实现线程安全等等 CPU的大部分时间都花在了“做事”上 而不是管理 李同步。< / p > < / >

  • not only offer better 吞吐量,但它们也提供 对生存的抵抗力更强 诸如死锁和 李优先级反转。< / p > < / >

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或围绕字段的读写同步来同步所使用的布尔变量。

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

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

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

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

摘自方案描述

atom描述:一个小的类工具包,支持对单个变量进行无锁线程安全编程。

这些方法的规范使实现能够使用在当代处理器上可用的高效的机器级原子指令。

AtomicBoolean、AtomicInteger、AtomicLong和AtomicReference类的实例都提供了对相应类型的单个变量的访问和更新。

原子的访问和更新的内存效果通常遵循volatile的规则:

  • Get具有读取volatile变量的内存效应。
  • Set具有写入(赋值)volatile变量的内存效果。
  • weakCompareAndSet原子地读取和有条件地写入一个变量,它是按照对该变量的其他内存操作排序的,但在其他方面,它是一个普通的非易失性内存操作。
  • compareAndSet和所有其他读取和更新操作(如getAndIncrement)都具有读取和写入volatile变量的内存效应。