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之间的值没有更改。
推荐文章
- 到底是什么导致了堆栈溢出错误?
- 为什么Android工作室说“等待调试器”如果我不调试?
- Java:路径vs文件
- ExecutorService,如何等待所有任务完成
- Maven依赖Servlet 3.0 API?
- 如何在IntelliJ IDEA中添加目录到应用程序运行概要文件中的类路径?
- getter和setter是糟糕的设计吗?相互矛盾的建议
- Android room persistent: AppDatabase_Impl不存在
- Java的String[]在Kotlin中等价于什么?
- Intellij IDEA上的System.out.println()快捷方式
- 使用Spring RestTemplate获取JSON对象列表
- Spring JPA选择特定的列
- URLEncoder不能翻译空格字符
- Java中的super()
- 如何转换JSON字符串映射<字符串,字符串>与杰克逊JSON