java - 原子引用

标签 java concurrency atomicreference

我对 AtomicReference.compareAndSet() 方法有一些疑问,根据文档,它说:

Atomically sets the value to the given updated value if the current value == the expected value.

据我了解, == 运算符正在比较两个对象的地址,如果是这样,它在这样的示例中将如何工作

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 如何知道要在 compareAndSet() 中比较 AccessStatistics 的哪些字段?事实上,我只是想知道,考虑到 java 根本不允许覆盖 == ,整个策略是如何工作的? 感谢您的任何评论!

最佳答案

how does jvm know which fields of AccessStatistics are to be compared in the compareAndSet()?

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

Atomically sets the value to the given updated value if the current value == the expected value.

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

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

关于java - 原子引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11691673/

相关文章:

java - 多核场景下编写java程序的技巧

java - 请解释最终的 AtomicReference

java - JMeter - 每个线程中的第一个样本很慢,问题每隔约 210 秒重复一次

java - 使用 ThreadLocals 的 Akka 和 Java 库

java - CompletableFuture.allOf() 在等待完成时是否比使用 CompletableFuture.join() 的循环有任何优势?

java - 限制对字段的并发访问

java - AtomicIntegerArray 中的数据争用

java - 工厂创建的对象可以有构造函数吗?

java.lang.NumberFormatException : For input string when using scanner to read the file 异常

java - JSF 中的线程安全