3

JMM(Java 内存模型)可以自由地重新排序语句。

当然,这在处理多线程环境时尤其棘手。

JMM 规则明确指出volatilefinal变量总是在构造函数完成之前完全初始化,并且当且仅当引用没有从构造函数中“逃脱”时。

这意味着任何并发线程都不会看到“正常”变量(非final和非)是最新的。volatile

乍一看,我的问题可能看起来很愚蠢,但实际上并非如此:

是否在构造函数完成后设置了任何对象的引用(完成并不意味着已经完成所有变量的初始化,而只是到达“构造函数”过程的结尾)?是否有任何 JSR 断言它的规则?或者它是否存在一个例外情况,在构造函数完成之前,任何引用都可以发送回客户端?

事实上,如果语句重新排序被认为如此自由,它也可能意味着对象的引用“发生在”构造函数的发送完成。因此,我们会遇到相同的“this逃跑”案例来避免。

简而言之,在构造函数完成后是否总是发送引用?

搜索 JLS 后:唯一与返回对象引用有关的地方是:(摘录JSR-12.5

就在对新创建对象的引用作为结果返回之前,使用以下过程处理指示的构造函数以初始化新对象:

与 JMM 无关……因此可以确保构造函数完成总是在传递引用之前发生。

4

1 回答 1

3

在线程的上下文中,将设置引用。但是,JMM 允许在一个线程中设置共享变量,但尚未同步到另一个线程。

volatile 和 final 通过保证对变量的读取和写入的线程间同步来保证这一点。

于 2012-10-22T01:58:21.157 回答