我有一些关于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不允许重写==,那么整个策略是如何工作的呢?谢谢您的评论!
发布于 2012-07-27 16:14:18
jvm如何知道AccessStatistics的哪些字段要在compareAndSet()中进行比较?
它没有。它不是比较对象中的字段。它只是比较对象的引用,这就是文档中所说的。这正是AtomicReference类的工作方式。正如您从javadocs中提到的,它使用的是==,而不是equals()方法。
如果当前值==为期望值,则原子地将值设置为给定的更新值。
所有的Atomic*类都具有类似的功能。它允许您原子地设置值,同时确保另一个线程不会覆盖您的值。使用compareAndSet(...),您必须指定当前的对象引用,以确保您正在按预期进行更新。
在您的代码片段中,它试图添加到不可变的访问统计对象中。因此,它获取当前值,将其添加,然后将新的统计数据存储到引用中。如果另一个线程在这段时间内存储了它的状态,那么compareAndSet将返回false,然后循环并再次尝试。这解决了不需要synchronized块的争用条件。
发布于 2012-07-27 16:14:17
JVM根本不对字段进行比较。它只是比较它是否是相同的引用,还是内存中的同一个指针,或者您想要调用它的任何东西。
https://stackoverflow.com/questions/11691673
复制相似问题