2017-04-12 63 views
2

我的代码包含一些AtomicBoolean字段。只调用这些字段的get()set()方法。仅当使用get()和set()方法时,用原始类型替换AtomicBoolean?

这些字段的类型可以安全地由原始布尔值替换吗?

我的意思是,原始布尔值的赋值和访问操作是Java中的原子操作。从这个角度来看,我看不出有什么理由在我的情况下使用AtomicBoolean

根据我的理解,AtomicBoolean只有在使用像compareAndSet这样的方法时才有意义,它将比较和访问相结合。我错了吗?你能解释为什么吗?

+4

太宽泛而没有显示有问题的代码,但一般的答案是否定的。 –

+1

您是否正在访问不同线程的字段? – VGR

+0

有两种类型的竞争条件:check-then-act和read-modify-write。如果用原始布尔值替换AtomicBoolean,你的问题将会是前者。 – mre

回答

5

原子变量实践被描述为“更好挥发物”Java并发(见15.3)。下面是这本书的摘录:

原子变量类提供volatile 变量的推广,以支持原子条件读 - 修改 - 写操作。 AtomicInteger代表int值,并提供具有与对 volatile int的读取和写入相同的存储器语义的方法getset 方法。

适用于你的情况,这意味着,如果你只使用get()set()AtomicBoolean方法,它们可以安全地读取写入volatile boolean更换。

volatile是需要的,以保证所有线程将看到最新变量的值。回到Java并发实践(3.1.4):

当某个字段声明volatile,编译器和运行时都穿上了 通知,这个变量是共享的,并且操作也应该 不与其他内存操作重新排序。Volatile变量为 未缓存在寄存器或缓存中,因为它们对其他 处理器隐藏,因此读取volatile变量总是返回最近由任何线程写入的最近 。

+0

谢谢你的回答。你能解释为什么原始布尔没有易失性不适合我的情况?或者,您是否可以描述在我的情况下使用原始布尔值时可能导致问题的场景? – eztam

+1

@eztam'AtomicBoolean'作为参考传递。如果你将'boolean'传递给两个线程,它们将不再具有共享值。 –

+2

@eztam。唯一可能导致使用原始'boolean'的问题是在_check-then-act_操作中使用它。在这种情况下,您应该使用AtomicBoolean(或使用同步)。 –

-1

答案是否定的。你可以在这里找到原因Why can't AtomicBoolean be a replacement for Boolean?

+2

这篇文章是关于相反的替代:用'AtomicBoolean'代替'Boolean'。 –

+0

是的。但是,当您阅读提供的答案时,可以解释AtomicBoolean是为并发目的而设计的单独的类。所以AtomicBoolean是线程安全的。所以你不能用原始布尔值替换它。 – MigSena

+0

如果您不想在代码中使用AtomicBoolean,则可以使用原始布尔值,但应该使用同步来自己处理线程安全属性。 – MigSena

2

这些字段的类型可以安全地用原始布尔值替换吗?

简单的原始boolean是不一样的AtomicBoolean(其提供了一种在多线程环境中的原子访问)。

但是,安全的替代选择可以是使用volatile boolean这也将提供原子访问,但我建议你保持AtomicBoolean的是(因为它提供了额外的API方法,在情况下,如果你可能是在未来)。

+0

谢谢,原始布尔和AtomicBoolean之间的区别对我来说很清楚。但是,你能否解释为什么在我的个人情况下无法取代它们? – eztam

+0

你能告诉我为什么你想这样做?我的意思是你期望从中得到什么?因为访问已经是原子的(因为你正在使用'AtomicBoolean'),所以你为什么要改变现有的行为? – developer