假设你有以下课程
public class AccessStatistics {
private final int noPages, noErrors;
public AccessStatistics(int noPages, int noErrors) {
this.noPages = noPages;
this.noErrors = noErrors;
}
public int getNoPages() { return noPages; }
public int getNoErrors() { return noErrors; }
}
并执行以下代码
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));
}
在最后两行
newValue = new AccessStatistics(noPages, noErrors);
while (!stats.compareAndSet(prev, newValue))
这是否意味着新创建的AccessStatistics实例与当前AccessStatistics实例具有相同的引用。怎么会这样 ?任何人都可以解释它。非常感谢。
答案 0 :(得分:3)
stats.compareAndSet(prev, newValue)
保留的当前引用不是stats
, prev
将失败并返回false。
通常,在多线程环境中,prev = stats.get();
和stats.compareAndSet(prev, newValue);
之间的另一个线程很可能会修改stats
所持有的引用。
stats.compareAndSet(prev, newValue);
真的说:
stats
仍然保留对prev
的引用,因为之前是5行,请更新它以保留对newValue
的引用stats
所持有的引用,则放弃我的计算并循环以重新计算新的newValue
。答案 1 :(得分:0)
新创建的对象是新的。在创建它的行之后,唯一引用它的是newValue
。没有别的可能 - 怎么可能? compareAndSet()
仅设置,如果没有其他内容同时将其设置为第三个值,除了您所知道的prev
以及您创建的新newValue
之外的其他值。