首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AtomicReference

AtomicReference
EN

Stack Overflow用户
提问于 2012-07-27 16:12:35
回答 2查看 1.2K关注 0票数 0

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

如果当前值==为期望值,则原子地将值设置为给定的更新值。

据我所知,==操作符正在比较两个对象的地址,如果是这样的话,在这样的示例中它将如何工作?

代码语言:javascript
复制
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不允许重写==,那么整个策略是如何工作的呢?谢谢您的评论!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-27 16:14:18

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

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

如果当前值==为期望值,则原子地将值设置为给定的更新值。

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

在您的代码片段中,它试图添加到不可变的访问统计对象中。因此,它获取当前值,将其添加,然后将新的统计数据存储到引用中。如果另一个线程在这段时间内存储了它的状态,那么compareAndSet将返回false,然后循环并再次尝试。这解决了不需要synchronized块的争用条件。

票数 5
EN

Stack Overflow用户

发布于 2012-07-27 16:14:17

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11691673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档