2012-10-22 36 views
3

JMM(Java Memory Model)可自由重新排列语句。对象的引用可以在其构造函数完成之前设置吗?

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

JMM规则精简了volatilefinal变量总是在构造函数完成之前完全初始化,并且当且仅当引用没有从构造函数中“转义”时。

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

我的问题可能乍一看愚蠢的,但它确实不是:

是任何对象的引用设置AFTER构造完成(完成不与已经取得的所有变量的初始化的意思,而只是达到'构造函数'过程的结尾)?任何JSR都有一个规则来断定它吗? 或者它可能存在一个例外的情况下,任何引用可以发回给客户端之前构造函数完成?事实上,如果语句重新排序被称为如此自由,它也可能意味着发送对象的引用'happen-before'构造函数完成。所以,我们会遇到“this转义”的相同情况以避免。

简而言之,引用ALWAYS在构造函数完成后会被发送吗?

搜索到JLS后:,回访对象的引用的有关的唯一的地方是:(的JSR-12.5节选)

只需到新创建的对象的引用之前,作为返回 结果,所指示的构造被处理使用下面的过程来初始化新 对象:

否relatio n到JMM ...因此可以确保构造函数的完成始终发生 - 无论何时传递参考。

+1

声明重新排序不是'很自由'。它受到JMM规则和JLS规定的严格限制。构造函数在返回之前必须完成执行。 – EJP

+0

@EJP谢谢。毫无疑问,现在整体有意义:) – Mik378

回答

3

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

易失性和最终保证这通过保证读取和写入变量的线程间同步。

+0

是的,引用将被设置,但是在构造函数被处理之后。看起来,构造函数完全跳过除final和volatile之外的变量(并发线程的眼睛),但事实上,这些变量并未同步到主内存中。 – Mik378

相关问题