的AtomicReference

Arr*_*Cen 0 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));
}
Run Code Online (Sandbox Code Playgroud)

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

Gra*_*ray 5

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

它没有.它不是比较对象中的字段.它只是比较对象的引用,这是文档所说的.这就是AtomicReference班级的运作方式.正如你在javadocs中提到的那样,它使用==而不是equals()方法.

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

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

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