Java 原子参考用法
假设你有下面的课程Java 原子参考用法,java,multithreading,compare-and-swap,Java,Multithreading,Compare And Swap,假设你有下面的课程 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; } publ
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));
}
这是否意味着新创建的AccessStatistics实例与当前AccessStatistics实例具有相同的引用。怎么可能呢?有人能解释一下吗。非常感谢。stats。如果stats
持有的当前引用不是prev
,则compareAndSet(prev,newValue)
将失败并返回false
通常,在多线程环境中,很可能在prev=stats.get()之间代码>和stats.compareAndSet(prev,newValue)
另一个线程会修改stats
持有的引用
stats.compareAndSet(prev,newValue)代码>真的说:
- 如果
stats
仍保留对prev
的引用,与之前的5行一样,则更新它以保留对newValue的引用
- 但是,如果另一个线程已经更改了自我上次在5行之前检查以来由
stats
持有的引用,则放弃我的计算并循环以重新计算新的newValue
新创建的对象是新的。在创建该行之后,唯一引用它的是
newValue
。没有别的办法,怎么可能呢?compareAndSet()
仅当同时没有其他值将其设置为第三个值时才进行设置,除了您知道的旧值prev
和您创建的新值newValue
之外
newValue = new AccessStatistics(noPages, noErrors);
while (!stats.compareAndSet(prev, newValue))