Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 原子参考用法_Java_Multithreading_Compare And Swap - Fatal编程技术网

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))