当http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight说
对象的最终字段的值在其构造函数中设置。假设对象是“正确”构造的,一旦构造了一个对象,分配给构造函数中最终字段的值对于所有其他线程都是可见的,而不进行同步。此外,这些最终字段引用的任何其他对象或数组的可见值将至少与最终字段一样是最新的。对象的正确构造意味着什么?它只是意味着在构造过程中不允许对正在构造的对象的引用“逃逸”。
这是否意味着只有看到不正确构造的对象的线程可能会看到它处于错误状态但所有其他线程都没问题?
例如,假设你有一些简单的代码
public class Foo {
final int x = 5;
public Foo() {
new Thread(() -> System.out.print(x)).start();
}
}
这是否意味着只有那个看过隐式this
引用的线程可能会出现可见性问题,但是使用Foo实例的任何其他线程都可以保证看到一个完全可见的Foo引用,它的字段x
为5?
JLS说,
当构造函数完成时,对象被认为是完全初始化的。在该对象完全初始化之后只能看到对象引用的线程可以保证看到该对象的
final
字段的正确初始化值。
没有迹象表明针对一个线程的可见性保证会受到另一个线程的不安全发布的影响。