根据文档,我对 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 不允许覆盖,整个策略是如何工作的 == 根本吗?感谢您的任何评论!

有帮助吗?

解决方案

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

事实并非如此。它不是比较对象中的字段。这只是比较 参考 对象的内容就是文档所说的。就是这样 AtomicReference 类作品。正如你提到的 java文档, , 它用 == 而不是 equals() 方法。

如果当前值 == 预期值,则自动将该值设置为给定的更新值。

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

在您的代码片段中,它试图添加到不可变的访问统计对象。因此它获取当前值,添加它,然后将新的统计数据存储到引用中。如果另一个线程存储了 它是 该时间之间的统计数据,然后 compareAndSet 将返回 false 并循环并再次尝试。这解决了竞争条件,而不必有 synchronized 堵塞。

其他提示

JVM 根本不比较字段。它 只是 比较它是否是相同的引用、内存中的相同指针或任何您想调用的名称。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top