是否有必要将AtomicReference声明为volatile?

时间:2011-08-12 06:45:04

标签: java thread-safety

所有其他原子对象都一样吗?解释AtomicInteger的问题更容易。由于超过1个线程正在访问对myInt的引用,因此对于此对象,一个线程是否可能看到已注册的缓存值,例如null,除非它也被声明为volatile?如果不是怎么来的?

2 个答案:

答案 0 :(得分:9)

不仅没有必要,它实际上在语义上是错误的。 AtomicReference在其自身内部保存“真实”引用,并使用自己的同步构造管理对它的访问。 JVM自己的同步构造(synchronizedvolatile等)并未使用。 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吗?答案取决于它。它们只是线程安全,只要它们正确发布,就像任何其他线程安全对象一样(除了不可变对象,这是特殊情况)。在大多数情况下,你应该让它们成为最终的。