可以在构造函数完成之前设置对象的引用吗?

时间:2012-10-22 01:26:05

标签: java constructor thread-safety jsr

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

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

JMM规则预先确定volatilefinal变量在构造函数完成之前总是被完全初始化,并且当且仅当引用没有从构造函数中“转义”时才会被初始化。

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

我的问题乍一看似乎很愚蠢,但事实并非如此:

是否有任何对象的引用集 AFTER 构造函数完成(完成并不意味着初始化已经生成的所有变量,而只是到达'构造函数'进程的末尾)?任何JSR断言都有规则吗? 或者它是否存在例外情况,任何引用都可以发送回客户端 BEFORE 构造函数完成?

实际上,如果声明重新排序被认为是如此自由,那么它也可能意味着发送对象的引用'发生在'之前'构造函数完成。所以,我们遇到了“this逃避”的相同情况,以避免。

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

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

  

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

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

1 个答案:

答案 0 :(得分:3)

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

通过保证对变量的读写操作的线程间同步来实现易失性和最终保证。