AtomicBoolean做了哪些volatile boolean不能做到的事情?


当前回答

Volatile关键字保证共享该变量的线程之间的happens-before关系。它不能保证2个或更多的线程在访问布尔变量时不会相互中断。

其他回答

AtomicBoolean有一些方法可以原子地执行复合操作,而不必使用同步块。另一方面,volatile布尔值只能在同步块中执行复合操作。

读取/写入volatile boolean的内存效果分别与AtomicBoolean的get和set方法相同。

例如,compareAndSet方法将自动执行以下操作(没有同步块):

if (value == expectedValue) {
    value = newValue;
    return true;
} else {
    return false;
}

因此,compareAndSet方法将允许您编写保证只执行一次的代码,即使是从多个线程调用时也是如此。例如:

final AtomicBoolean isJobDone = new AtomicBoolean(false);

...

if (isJobDone.compareAndSet(false, true)) {
    listener.notifyJobDone();
}

保证只通知侦听器一次(假设没有其他线程将AtomicBoolean设置为true后再次设置为false)。

你不能将compareAndSet, getAndSet作为带有volatile boolean的原子操作(除非你同步它)。

Volatile关键字保证共享该变量的线程之间的happens-before关系。它不能保证2个或更多的线程在访问布尔变量时不会相互中断。

如果有多个线程访问类级别变量,则 每个线程都可以在其线程本地缓存中保留该变量的副本。

将变量设置为volatile将防止线程将变量的副本保存在线程本地缓存中。

原子变量是不同的,它们允许对其值进行原子修改。

布尔基元类型是原子的,用于写和读操作,volatile保证happens before原则。因此,如果您需要一个简单的get()和set(),那么您不需要AtomicBoolean。

另一方面,如果你需要在设置一个变量的值之前执行一些检查,例如。"如果为真,则设置为假",那么您也需要原子地执行此操作,在这种情况下使用compareAndSet和AtomicBoolean提供的其他方法,因为如果您尝试使用volatile boolean实现此逻辑,则需要一些同步来确保get和set之间的值没有更改。