简体   繁体   English

安全初始化非最终字段

[英]safe initialization of non final fields

From Java theory and practice: Fixing the Java Memory Model, Part 2 Java理论和实践:修复Java内存模型,第2部分

The new JMM also seeks to provide a new guarantee of initialization safety -- that as long as an object is properly constructed (meaning that a reference to the object is not published before the constructor has completed), then all threads will see the values for its final fields that were set in its constructor, regardless of whether or not synchronization is used to pass the reference from one thread to another.

So what is about non final fields initialized in constructor? 那么在构造函数中初始化的非final字段是什么? From a reference to the object is not published before the constructor has completed I could conclude that behaviour is same as for final fields. a reference to the object is not published before the constructor has completed我可以得出结论,行为与final字段相同。 Is it correct? 这是正确的吗?

Take this simple class: 拿这个简单的课:

class Example {
    final int i;
    int j;
    Example() { i = 5; j = 5; }
}

No reference to the object is published during construction, so the JMM guarantees that all reading threads that access a newly created instance of Example will see i = 5 . 在构造期间不会发布对该对象的引用,因此JMM保证访问新创建的Example实例的所有读取线程都将看到i = 5 That is the case regardless of how the instance is published. 无论实例如何发布都是如此。

Those same threads might however see j = 0 (ie the default value) if the instance is not published safely. 但是,如果实例未安全发布,那些相同的线程可能会看到j = 0 (即默认值)。 Safe publication idioms include: 安全出版习语包括:

  • initialising the instance from a static initialiser 从静态初始化器初始化实例
  • marking the reference to the instance as volatile 将对实例的引用标记为volatile
  • marking the reference to the instance as final 将对实例的引用标记为final
  • synchronizing all accesses 同步所有访问
  • For volatile variables, writes are guaranteed to be immediately visible to all threads. 对于volatile变量,保证写入对所有线程立即可见。 This is the case whether or not the write was done in a constructor. 无论写入是否在构造函数中完成,都是这种情况。

  • For non-volatile variables, writes may not immediately be visible to other threads. 对于非易失性变量,写入可能不会立即对其他线程可见。 This is the case whether or not the write was done in a constructor. 无论写入是否在构造函数中完成,都是这种情况。

A special case is final fields. 一个特例是最终字段。 Writes to an object's final fields are guaranteed to be visible to all threads once the constructor has been completed. 一旦构造函数完成,保证对所有线程都可以写入对象的最终字段。

You can read more here . 你可以在这里阅读更多。

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

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