AtomicBoolean做了哪些volatile boolean不能做到的事情?
当前回答
I use volatile fields when said field is ONLY UPDATED by its owner thread and the value is only read by other threads, you can think of it as a publish/subscribe scenario where there are many observers but only one publisher. However if those observers must perform some logic based on the value of the field and then push back a new value then I go with Atomic* vars or locks or synchronized blocks, whatever suits me best. In many concurrent scenarios it boils down to get the value, compare it with another one and update if necessary, hence the compareAndSet and getAndSet methods present in the Atomic* classes.
检查java.util.concurrent.atomic包中的JavaDocs,以获得Atomic类的列表和它们如何工作的出色解释(刚刚了解到它们是无锁的,因此它们比锁或同步块更有优势)
其他回答
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原则。因此,如果您需要一个简单的get()和set(),那么您不需要AtomicBoolean。
另一方面,如果你需要在设置一个变量的值之前执行一些检查,例如。"如果为真,则设置为假",那么您也需要原子地执行此操作,在这种情况下使用compareAndSet和AtomicBoolean提供的其他方法,因为如果您尝试使用volatile boolean实现此逻辑,则需要一些同步来确保get和set之间的值没有更改。
I use volatile fields when said field is ONLY UPDATED by its owner thread and the value is only read by other threads, you can think of it as a publish/subscribe scenario where there are many observers but only one publisher. However if those observers must perform some logic based on the value of the field and then push back a new value then I go with Atomic* vars or locks or synchronized blocks, whatever suits me best. In many concurrent scenarios it boils down to get the value, compare it with another one and update if necessary, hence the compareAndSet and getAndSet methods present in the Atomic* classes.
检查java.util.concurrent.atomic包中的JavaDocs,以获得Atomic类的列表和它们如何工作的出色解释(刚刚了解到它们是无锁的,因此它们比锁或同步块更有优势)
Volatile关键字保证共享该变量的线程之间的happens-before关系。它不能保证2个或更多的线程在访问布尔变量时不会相互中断。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap