题
根据文档,我对 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 根本不比较字段。它 只是 比较它是否是相同的引用、内存中的相同指针或任何您想调用的名称。
不隶属于 StackOverflow