首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AtomicReference使用率

AtomicReference使用率
EN

Stack Overflow用户
提问于 2012-07-15 23:50:19
回答 2查看 406关注 0票数 1

假设你有下面的类

代码语言:javascript
复制
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; }
}

然后执行以下代码

代码语言:javascript
复制
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));
}

在最后两行中

代码语言:javascript
复制
newValue = new AccessStatistics(noPages, noErrors);
while (!stats.compareAndSet(prev, newValue)) 

这是否意味着新创建的AccessStatistics实例与当前AccessStatistics实例具有相同的引用。怎么会这样呢?有人能解释一下吗。非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-15 23:56:50

如果stats持有的当前引用不是prev,则stats.compareAndSet(prev, newValue)将失败并返回false。

通常,在多线程环境中,在prev = stats.get();stats.compareAndSet(prev, newValue);之间,另一个线程很可能已经修改了stats持有的引用。

stats.compareAndSet(prev, newValue);真的说:

  • 如果stats仍然持有对prev的引用,就像之前的5行一样,更新它以持有对newValue
  • if的引用,但是自从我上次检查了5行之后,另一个线程已经更改了stats持有的引用,放弃我的计算并循环以重新计算新的
票数 3
EN

Stack Overflow用户

发布于 2012-07-15 23:57:26

新创建的对象是新的。在创建它的那一行之后,唯一引用它的是newValue。别的什么都不能--怎么可能?除了你所知道的关于prev的旧的和你创建的newValue的新的值之外,只有在没有其他设置的情况下,compareAndSet()才会设置成第三个值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11493309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档