我的问题适用于最初为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();
}
…
}
答案 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