AtomicBoolean做了哪些volatile boolean不能做到的事情?
当前回答
Volatile boolean vs AtomicBoolean
Atomic*类包装了相同类型的volatile原语。来源:
public class AtomicLong extends Number implements java.io.Serializable {
...
private volatile long value;
...
public final long get() {
return value;
}
...
public final void set(long newValue) {
value = newValue;
}
如果你所做的只是获取和设置一个Atomic*,那么你也可以用一个volatile字段来代替。
AtomicBoolean做了哪些volatile boolean不能做到的事情?
原子类为您提供了提供更高级功能的方法,例如用于数字的incrementAndGet(),用于布尔值的compareAndSet(),以及其他实现多重操作(get/increment/set, test/set)而无需锁定的方法。这就是为什么Atomic*类如此强大。
例如,如果多个线程使用++使用下面的代码,就会出现竞争条件,因为++实际上是:get、increment和set。
private volatile value;
...
// race conditions here
value++;
然而,下面的代码将在多线程环境中安全工作,没有锁:
private final AtomicLong value = new AtomicLong();
...
value.incrementAndGet();
同样重要的是要注意,从对象的角度来看,使用Atomic*类包装volatile字段是封装关键共享资源的好方法。这意味着开发人员不能假设字段不共享就处理它,可能会在字段++中注入问题;或其他引入竞态条件的代码。
其他回答
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 boolean vs AtomicBoolean
Atomic*类包装了相同类型的volatile原语。来源:
public class AtomicLong extends Number implements java.io.Serializable {
...
private volatile long value;
...
public final long get() {
return value;
}
...
public final void set(long newValue) {
value = newValue;
}
如果你所做的只是获取和设置一个Atomic*,那么你也可以用一个volatile字段来代替。
AtomicBoolean做了哪些volatile boolean不能做到的事情?
原子类为您提供了提供更高级功能的方法,例如用于数字的incrementAndGet(),用于布尔值的compareAndSet(),以及其他实现多重操作(get/increment/set, test/set)而无需锁定的方法。这就是为什么Atomic*类如此强大。
例如,如果多个线程使用++使用下面的代码,就会出现竞争条件,因为++实际上是:get、increment和set。
private volatile value;
...
// race conditions here
value++;
然而,下面的代码将在多线程环境中安全工作,没有锁:
private final AtomicLong value = new AtomicLong();
...
value.incrementAndGet();
同样重要的是要注意,从对象的角度来看,使用Atomic*类包装volatile字段是封装关键共享资源的好方法。这意味着开发人员不能假设字段不共享就处理它,可能会在字段++中注入问题;或其他引入竞态条件的代码。
布尔基元类型是原子的,用于写和读操作,volatile保证happens before原则。因此,如果您需要一个简单的get()和set(),那么您不需要AtomicBoolean。
另一方面,如果你需要在设置一个变量的值之前执行一些检查,例如。"如果为真,则设置为假",那么您也需要原子地执行此操作,在这种情况下使用compareAndSet和AtomicBoolean提供的其他方法,因为如果您尝试使用volatile boolean实现此逻辑,则需要一些同步来确保get和set之间的值没有更改。
你不能将compareAndSet, getAndSet作为带有volatile boolean的原子操作(除非你同步它)。
如果你只有一个线程修改你的布尔值,你可以使用一个volatile布尔值(通常你这样做是为了在线程的主循环中定义一个停止变量)。
但是,如果有多个线程修改布尔值,则应该使用AtomicBoolean。否则,以下代码是不安全的:
boolean r = !myVolatileBoolean;
该操作分两步完成:
读取布尔值。 写入布尔值。
如果其他线程修改了#1到2#之间的值,您可能会得到错误的结果。AtomicBoolean方法通过原子地执行步骤#1和#2来避免这个问题。
推荐文章
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂
- Java:检查enum是否包含给定的字符串?
- 它的意思是:序列化类没有声明一个静态的最终serialVersionUID字段?