【发布时间】:2011-05-28 22:10:45
【问题描述】:
我如何使用 AtomicBoolean 以及该类的用途是什么?
【问题讨论】:
-
相关:
volatile booleanvsAtomicBoolean:stackoverflow.com/questions/3786825/…
标签: java concurrency
我如何使用 AtomicBoolean 以及该类的用途是什么?
【问题讨论】:
volatile boolean vs AtomicBoolean:stackoverflow.com/questions/3786825/…
标签: java concurrency
当多个线程需要检查和更改布尔值时。例如:
if (!initialized) {
initialize();
initialized = true;
}
这不是线程安全的。您可以使用AtomicBoolean 修复它:
if (atomicInitialized.compareAndSet(false, true)) {
initialize();
}
【讨论】:
initialize() 尚未完成时,其他线程可以看到true。因此,它仅在其他线程不关心 initialize() 的完成时才有效。
initialized 仅用于确保只有一个线程将调用initialize() 方法,我认为这是一个完全有效的真实示例。显然initialized 为真并不意味着在这种情况下初始化肯定已经完成,所以也许在这里稍微不同的术语会更好。同样,这取决于它的用途。
volatile boolean 不会与AtomicBoolean 相同吗?。
compareAndSet 这样的功能,如果没有某种同步,这些功能实际上是无法实现的
这是我做的笔记(来自Brian Goetz book),可能对你有帮助
AtomicXXX 类
提供非阻塞比较和交换实现
利用提供的支持 通过硬件(CMPXCHG 指令 在 Intel 上)当有很多线程时 运行您使用的代码 这些原子并发 API,他们 将比代码更好地扩展 它使用对象级别 监视器/同步。自从, Java的同步机制 让代码等待,当有很多 通过你的线程运行 关键部分,一个实质性的 花费的 CPU 时间量 管理同步 机制本身(等待、通知、 等等)。由于新 API 使用硬件 级别构造(原子变量) 并等待并锁定免费算法 实现线程安全等等 的 CPU 时间用于“做事” 而不是在管理 同步。
不仅提供更好的 吞吐量,但它们也提供 对活力的抵抗力更强 死锁等问题 优先级倒置。
【讨论】:
您可以使用原子布尔值有两个主要原因。首先它是可变的,例如,您可以将其作为引用传递并更改与布尔值本身关联的值。
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 或围绕字段的读取和写入同步来同步您正在使用的布尔变量。
【讨论】:
AtomicBoolean 类为您提供一个布尔值,您可以自动更新该值。当你有多个线程访问一个布尔变量时使用它。
java.util.concurrent.atomic package overview 为您提供了有关此包中的类的作用以及何时使用它们的良好高级描述。我还推荐 Brian Goetz 的书 Java Concurrency in Practice。
【讨论】:
包 java.util.concurrent.atomic 描述:一个小类工具包,支持对单个变量进行无锁线程安全编程。[...]
这些方法的规范使实现能够使用现代处理器上可用的高效机器级原子指令。[...]
AtomicBoolean、AtomicInteger、AtomicLong 和 AtomicReference 类的实例均提供对相应类型的单个变量的访问和更新。[...]
atomics 的访问和更新的记忆效应一般遵循 volatiles 的规则:
- get 具有读取 volatile 变量的记忆效应。
- set 具有写入(分配)易失性变量的记忆效应。
- weakCompareAndSet 以原子方式读取和有条件地写入变量,相对于对该变量的其他内存操作进行排序,但在其他方面充当普通的非易失性内存操作。
- compareAndSet 和所有其他读取和更新操作(例如 getAndIncrement)具有读取和写入 volatile 变量的记忆效应。
【讨论】: