什么时候使用AtomicReference?

在所有多线程程序中都需要创建对象吗?

提供一个使用AtomicReference的简单示例。


当前回答

原子引用应该用于需要对引用执行简单的原子(即线程安全的、非平凡的)操作的设置,对于这种情况,基于监视器的同步并不合适。假设你只想在对象的状态在处理过程中发生改变时才设置一个特定的字段:

AtomicReference<Object> cache = new AtomicReference<Object>();

Object cachedValue = new Object();
cache.set(cachedValue);

//... time passes ...
Object cachedValueToUpdate = cache.get();
//... do some work to transform cachedValueToUpdate into a new version
Object newValue = someFunctionOfOld(cachedValueToUpdate);
boolean success = cache.compareAndSet(cachedValue,cachedValueToUpdate);

由于原子引用语义,即使缓存对象在线程之间共享,也可以这样做,而不需要使用synchronized。一般来说,最好使用同步器或java.util.concurrent框架,而不是直接使用Atomic*,除非你知道自己在做什么。

两篇优秀的参考文献将介绍你这个主题:

Herlihy优秀的多处理器编程艺术 Java并发性实践

注意(我不知道这是否一直正确)引用赋值(即=)本身是原子的(更新基本64位类型,如long或double可能不是原子的;但是更新引用总是原子的,即使它是64位),而不显式地使用atomic *。 请参见Java语言规范3ed,第17.7节。

其他回答

原子引用应该用于需要对引用执行简单的原子(即线程安全的、非平凡的)操作的设置,对于这种情况,基于监视器的同步并不合适。假设你只想在对象的状态在处理过程中发生改变时才设置一个特定的字段:

AtomicReference<Object> cache = new AtomicReference<Object>();

Object cachedValue = new Object();
cache.set(cachedValue);

//... time passes ...
Object cachedValueToUpdate = cache.get();
//... do some work to transform cachedValueToUpdate into a new version
Object newValue = someFunctionOfOld(cachedValueToUpdate);
boolean success = cache.compareAndSet(cachedValue,cachedValueToUpdate);

由于原子引用语义,即使缓存对象在线程之间共享,也可以这样做,而不需要使用synchronized。一般来说,最好使用同步器或java.util.concurrent框架,而不是直接使用Atomic*,除非你知道自己在做什么。

两篇优秀的参考文献将介绍你这个主题:

Herlihy优秀的多处理器编程艺术 Java并发性实践

注意(我不知道这是否一直正确)引用赋值(即=)本身是原子的(更新基本64位类型,如long或double可能不是原子的;但是更新引用总是原子的,即使它是64位),而不显式地使用atomic *。 请参见Java语言规范3ed,第17.7节。