如果包装类已经是不可变的,为什么我们需要Atomic *类?

时间:2016-09-14 05:46:08

标签: java multithreading concurrency

我最近遇到了来自java.util.concurrent.atomic包的原子类。据我所知,不可变类本质上是默认的线程安全,所以我们不需要同步它们。后来我才知道Integer,Boolean,Character等包装类本质上是不可变的,为什么我们需要像AtomicInteger或AtomicLong这样的Atomic *类。另外,请解释什么是AtomicReference

4 个答案:

答案 0 :(得分:6)

原子类是 mutable ,但在修改方面具有强大的内存一致性保证。因此它们与不可变包装类的用途不同。

Atomic*类的真正优势在于它们公开了一个原子compare-and-swap方法,这对于实现lock-free algorithms非常有用。

与许多中级到高级并发工具一样,如果您无法想象为什么需要这样的东西,那么您可能不应该尝试使用它们。如果你坚持不变性或在任何地方显式锁定,那么你可能不需要原子。

答案 1 :(得分:2)

Here是关于compareAndSet原则的一个很好的问题。

来自文档:

  • 这些方法的规范使实现能够采用当代处理器上可用的高效机器级原子指令。

阅读atomic / volatile / synchronized将有助于您保持它们之间的差异。

答案 2 :(得分:0)

你有没有想过我什么时候有Integer(1),怎么能把它改成Integer(2),整数是不可变的。所以我需要创建一个新的并设置它的值,但这个过程不是原子的

答案 3 :(得分:0)

原子性的概念来自于某些东西是可变的。 我们希望修改字段/变量(可以是许多步骤,读取 - >更新 - >写入)作为原子操作的操作。因此,在多线程场景中,不应存在任何数据损坏。 java.util.concurrent.atomic包为我们做了。 包装类是不可变的,我们不能修改它,需要创建一个新实例。