JMM(Java 内存模型)可以自由地重新排序语句。
当然,这在处理多线程环境时尤其棘手。
JMM 规则明确指出volatile
,final
变量总是在构造函数完成之前完全初始化,并且当且仅当引用没有从构造函数中“逃脱”时。
这意味着任何并发线程都不会看到“正常”变量(非final
和非)是最新的。volatile
乍一看,我的问题可能看起来很愚蠢,但实际上并非如此:
是否在构造函数完成后设置了任何对象的引用(完成并不意味着已经完成所有变量的初始化,而只是到达“构造函数”过程的结尾)?是否有任何 JSR 断言它的规则?或者它是否存在一个例外情况,在构造函数完成之前,任何引用都可以发送回客户端?
事实上,如果语句重新排序被认为如此自由,它也可能意味着对象的引用“发生在”构造函数的发送完成。因此,我们会遇到相同的“this
逃跑”案例来避免。
简而言之,在构造函数完成后是否总是发送引用?
搜索 JLS 后:唯一与返回对象引用有关的地方是:(摘录JSR-12.5)
就在对新创建对象的引用作为结果返回之前,使用以下过程处理指示的构造函数以初始化新对象:
与 JMM 无关……因此可以确保构造函数完成总是在传递引用之前发生。