2016-04-08 27 views
3

我想了解這是對JDK做了更改:併發性 - 爲什麼使用嵌套子類作爲最終靜態字段?

http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/223be1d3494f

在此之前的變化,使用雙重檢查鎖定,以確保線程安全,這導致的問題。

他們爲什麼還要使用另一個子類?爲什麼他們不是簡單地在StrictMath中使用static final Random randomNumberGenerator = new Random();

,或者更一般的,爲什麼會這樣:

標準的技術是有一個嵌套子與需求初始化的最終場 (懶洋洋)

(從https://bugs.openjdk.java.net/browse/JDK-6470700

+0

* 「爲什麼他們不能簡單地用靜態最終隨機randomNumberGenerator =新的隨機();」 * - 也許,以節省內存。 'Math.random()'很少使用。 –

回答

5

這是按需初始化持有人成語,如的第48項中所述有效Java

參見:https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom

參見:Correct implementation of initialization-on-demand holder idiom

+0

好吧,所以不直接在StrictMath中使用靜態最終字段的唯一原因是讓它懶惰地初始化,它不是嚴格需要併發嗎? – Polygnome

+1

@Polygnome這是得到*既*惰性初始化*和*線程安全性較低的成本/更簡單比使用雙重檢查鎖定。 (DCL曾經是不安全的;從Java 5開始,它只是複雜且容易出錯) –

+0

好的,謝謝,如果你將最後一個評論添加到答案中,它是完美的;)瞭解成語的名字已經幫助我找到了很多附加信息。 – Polygnome

1

如果您在父項中使用靜態最終字段,則不會進行延遲初始化。 當類首次被使用並被加載時,一個類的靜態字段被初始化。 因此,如果您在父類中有一個靜態最終字段,那麼只要引用外部類,它就會被初始化。

通過使用這個習慣用法,你有惰性加載,因爲內部類的靜態最終字段只在初次使用時需要初始化。

+2

問題是*爲什麼*,我不認爲它是這樣做的,具體而言,爲什麼它不在父項中使用靜態最終字段。 – Polygnome

相關問題