安全初始化非最终字段

时间:2013-05-28 09:20:00

标签: java concurrency initialization

来自Java theory and practice: Fixing the Java Memory Model, Part 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.

那么在构造函数中初始化的非最终字段是什么?从a reference to the object is not published before the constructor has completed我可以得出结论,行为与最终字段相同。这是对的吗?

2 个答案:

答案 0 :(得分:3)

选择这个简单的课程:

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

在构造期间不会发布对象的引用,因此JMM保证访问新创建的Example实例的所有读取线程都将看到i = 5。无论实例如何发布,都是如此。

如果实例未安全发布,那些相同的线程可能会看到j = 0(即默认值)。安全出版习语包括:

  • 从静态初始化程序初始化实例
  • 将对实例的引用标记为volatile
  • 将对实例的引用标记为最终
  • 同步所有访问

答案 1 :(得分:1)

  • 对于volatile变量,保证写入对所有线程立即可见。无论写入是否在构造函数中完成,都是这种情况。

  • 对于非易失性变量,其他线程可能无法立即看到写入。无论写入是否在构造函数中完成,都是这种情况。

特殊情况是最终字段。一旦构造函数完成,保证对所有线程都可以写入对象的最终字段。

您可以阅读更多here