为什么AtomicBoolean不能替代布尔值?

Bro*_*oks 32 java api-design

AtomicBoolean的Oracle JDK Javadoc声明:

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicBoolean.html

可以原子方式更新的布尔值.有关原子变量属性的描述,请参阅java.util.concurrent.atomic包规范.AtomicBoolean用于诸如原子更新标志的应用程序中,不能用作布尔值的替代.

一位同事和我试图找出一个用例,其中AtomicBoolean不能替代,我们唯一能想到的是布尔对象有的方法,而AtomicBoolean却没有.

这是唯一的原因还是在撰写时还有其他想法?

Nat*_*hes 53

Boolean是一个不可变的值对象.它被设计为不变的并且是最终的,以便执行它.java.lang.Boolean从1.0开始就存在.

AtomicBoolean是可变的,旨在进行更新,以便跨线程可以看到更新的值.AtomicBoolean是随Java 5引入的.

这些是完全不同的概念,这就是为什么AtomicBoolean不是为扩展布尔而设计的.在不使用它破坏代码的预期不变量的情况下,您不能将可变对象替换为不可变对象.如果原子版本可以在其位置传入,则期望接收不可变值的代码可能会被破坏.

所以这是一个用例:如果AtomicBoolean是作为可替代布尔值的东西引入的,那么你可能会遇到这样一种情况:在这个改变之前创建的一个类可以合理地期望在一些返回布尔值的方法中它不需要通过防御由于布尔值是不可变的而复制.如果返回的引用恰好从更改为使用AtomicBoolean而不是Boolean的源进行初始化,那么现在可以通过调用返回布尔值的方法修改该字段,方法是将其转换为AtomicBoolean.

原子类设计用于处理并发更新(作为改进volatile),但设计并发代码的最有效方法是使用不可变值.因此,请注意不要将AtomicBoolean误认为"编写多线程代码时使用的布尔值".


man*_*uti 33

Boolean是原语周围的包装类boolean.它可以boolean由编译器自动创建(装箱转换)或转换为布尔值(拆箱转换).对于AtomicBoolean它是为并发目的而设计的单独类,情况并非如此.

因此,这两个类在语言级别具有不同的语义:

Boolean b = new Boolean(true);
AtomicBoolean ab = new AtomicBoolean(true);
System.out.println(true == b);  // automatic unboxing of Boolean variable
System.out.println(true == ab);  // compiler error
Run Code Online (Sandbox Code Playgroud)

  • 这与戴夫的答案一起回答了我们的问题.感觉就像试图决定向谁捐钱给亿万富翁或亿万富翁,所以最终它归结为解释性质,我首先看到了这一点. (4认同)