我最近遇到了来自java.util.concurrent.atomic包的原子类。据我所知,不可变类本质上是默认的线程安全,所以我们不需要同步它们。后来我才知道Integer,Boolean,Character等包装类本质上是不可变的,为什么我们需要像AtomicInteger或AtomicLong这样的Atomic *类。另外,请解释什么是AtomicReference。
答案 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包为我们做了。 包装类是不可变的,我们不能修改它,需要创建一个新实例。