何时使用AtomicReference(Java)?它真的必要吗?

9

我已经多次使用过AtomicLong,但从未需要使用过AtomicReference。

看起来AtomicReference执行以下操作(我从另一个stackoverflow问题中复制了此代码):

public synchronized boolean compareAndSet(List<Object> oldValue, List<Object> newValue) { 
    if (this.someList == oldValue) {
        // someList could be changed by another thread after that compare,
        // and before this set
        this.someList = newValue;
        return true;
    }
    return false;
}

或者
public synchronized boolean compareAndSet(List<Object> oldValue, List<Object> newValue) { 
    if (this.someList == oldValue || this.someList.equals(oldValue)) {
        // someList could be changed by another thread after that compare,
        // and before this set
        this.someList = newValue;
        return true;
    }
    return false;
}

假设 this.someList 被标记为 volatile。
我不确定它是哪一个,因为该类的 javadoc 和代码并没有明确说明是否使用了 .equals 方法。
由于上述方法并不难编写,因此有人使用过 AtomicReference 吗?

6
他们曾经使用过它。 - BalusC
1个回答

15

这是一个引用,所以这就是比较的对象。文档非常清楚地说明了它是一个身份比较,甚至在其描述中使用了==操作。

我经常使用AtomicReference和其他原子类。分析显示它们的性能优于使用同步的等效方法。例如,对AtomicReference执行get()操作仅需要从主内存中获取,而使用synchronized进行类似操作必须首先将线程缓存的任何值刷新到主内存中,然后执行其获取操作。

AtomicXXX类提供对比较并交换(CAS)操作的本机支持。如果底层系统支持它,则CAS将比纯Java中使用synchronized块设计的任何方案更快。


1
当然,我是个白痴。它是java.lang.ref。我一直以为它像AtomicObject一样,如果有的话。 - Adam Gent
你会如何评论这个基准测试:https://edgblog.wordpress.com/2013/10/01/synchronization-vs-atomicreference-test/? - Waldemar Wosiński
使用 AtomicLong 来维护值会比在 synchronized 块中使用 long 更快,这是一种直接的苹果对苹果比较。对象分配占了一部分差异,但由于 CAS 失败比较而导致的重试加剧了这种差异。如果你关心并发应用程序的速度,那么请坚持执行没有副作用的操作(例如 longAtomicLong 实现)。 - erickson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接