的AtomicReference

时间:2012-07-27 16:12:36

标签: java concurrency atomicreference

根据文档,我得到了一些关于AtomicReference.compareAndSet()方法的问题,它说:

  

如果当前值==预期值,则以原子方式将值设置为给定的更新值。

据我所知,==运算符正在比较两个对象的地址,如果是这样,它将如何在这样的例子中起作用

private AtomicReference<AccessStatistics> stats =
    new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
    AccessStatistics prev, newValue;
    do {
        prev = stats.get();
        int noPages = prev.getNoPages() + 1;
        int noErrors = prev.getNoErrors;
        if (wasError) {
           noErrors++;
        }
        newValue = new AccessStatistics(noPages, noErrors);
    } while (!stats.compareAndSet(prev, newValue));
}

在此代码段中,jvm如何知道AccessStatistics中哪些compareAndSet()字段要进行比较?事实上,我只是想知道如果java根本不允许覆盖==,整个策略是如何工作的? 感谢您的任何评论!

2 个答案:

答案 0 :(得分:5)

  

jvm如何知道在compareAndSet()中要比较哪些AccessStatistics字段?

没有。它不是比较对象中的字段。它只是比较对象的引用,这是文档所说的。这就是AtomicReference类的工作原理。正如您在javadocs中提到的那样,它使用的是==而不是equals()方法。

  

如果当前值==预期值,则以原子方式将值设置为给定的更新值。

所有Atomic*类都具有类似的功能。它允许您以原子方式设置值,同时确保另一个线程不会覆盖您的值。使用compareAndSet(...),您必须指定当前对象引用,以确保按预期更新。

在您的代码段中,它尝试添加到不可变的访问统计对象。因此,它获取当前值,添加到它,然后将新统计信息存储到引用。如果另一个线程在那个时间之间存储统计信息,那么compareAndSet将返回false并且它会循环并再次尝试。这解决了竞争条件,而无需synchronized阻止。

答案 1 :(得分:2)

JVM根本不比较字段。 只是比较它是否是相同的引用,内存中的相同指针,或者你想要调用它的任何东西。