简体   繁体   English

混合挥发性和非挥发性

[英]Mixing volatile and non-volatile

My question applies to a field which is initially null , then is initialised to a non- null value, and then doesn't change anymore. 我的问题适用于最初为null ,然后初始化为非null值,然后不再更改的字段。

As this field needs to be available as soon as possible to all threads, I need to use volatile . 由于此字段需要尽快对所有线程可用,因此我需要使用volatile

But if I want to avoid the overhead of volatile access whenever possible (ie when a non- volatile field is enough), would the following code make any sense? 但是,如果我想尽可能避免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();
  }

  …
}

Yeah, the code will work because "A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field." 是的,该代码将起作用,因为“在随后每次对该字段进行读取之前,都会对该易失字段(第8.3.1.4节)进行写操作”。 [1] [1]

return name != null ? name : volatileName;

so as long as name == null you will be forcing a read from a volatile variable until it is not null (ie expensiveComputation has completed) which given the happen before semantics ensures that you see the non null value in nonVolatileName from then onward. 因此,只要name == null ,就将强制从volatile变量中读取数据,直到它不为null(即, expensiveComputation已完成)为止。在语义确保从那时起,您会在nonVolatileName看到非null值之前,这种情况已经发生。 See also here [2] 另请参见[2]

Have fun explaining this to your colleagues though 还是很高兴向你的同事解释这一点

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

[2] Volatile variables and other variables [2] 易变变量和其他变量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM