所有其他原子对象都一样吗?解释AtomicInteger的问题更容易。由于超过1个线程正在访问对myInt的引用,因此对于此对象,一个线程是否可能看到已注册的缓存值,例如null,除非它也被声明为volatile?如果不是怎么来的?
答案 0 :(得分:9)
不仅没有必要,它实际上在语义上是错误的。 AtomicReference
在其自身内部保存“真实”引用,并使用自己的同步构造管理对它的访问。 JVM自己的同步构造(synchronized
,volatile
等)并未使用。 AtomicReference
对象本身不应被视为volatile。如果有的话,请考虑将其final
。
另外考虑this question - volatile
可以被视为使用AtomicReference
的替代方法,如果您只需要获取和设置操作。
答案 1 :(得分:2)
“atomic”对象不是不可变的,因此只有正确发布它们才应该是线程安全的。例如,当您执行此类操作时,您将需要使用volatile关键字。
volatile AtomicInteger counter = // initialize counter
int harvest(){
AtomicInteger old = counter;
counter = new AtomicInteger();
return old.get();
}
如果从上面的代码中删除volatile,你的确可能会失去一些增量。根据规范,您可能还会获得对未完全构造的AtomicInteger对象的引用,从而获得未定义的行为。
那么,你需要将你的原子对象声明为volatile吗?答案取决于它。它们只是线程安全,只要它们正确发布,就像任何其他线程安全对象一样(除了不可变对象,这是特殊情况)。在大多数情况下,你应该让它们成为最终的。