混合挥发性和非挥发性

时间:2019-11-25 16:56:37

标签: java multithreading volatile

我的问题适用于最初为null,然后初始化为非null值,然后不再更改的字段。

由于该字段需要尽快对所有线程可用,因此我需要使用volatile

但是,如果我想尽可能避免volatile访问的开销(即,当非volatile字段足够时),下面的代码有意义吗?

public class User {
  private String nonVolatileName;
  private volatile String volatileName;

  public String getName() {
    final String name = nonVolatileName;
    return name != null ? name : volatileName;
  }

  private void initName() {
    volatileName = nonVolatileName = expensiveComputation();
  }

  …
}

1 个答案:

答案 0 :(得分:3)

是的,代码之所以有效,是因为“在随后每次对该字段进行读取之前,都会写入一个易失字段(第8.3.1.4节)。” [1]

return name != null ? name : volatileName;

只要name == null就会强制从volatile变量中读取数据,直到它不为null(即expensiveComputation已完成)为止。从那时起nonVolatileName中的值。另请参见[2]

不过,还是很高兴向您的同事解释这一点

[1] https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5-320

[2] Volatile variables and other variables