2012-10-22 73 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

相關問題