2012-08-22 57 views

回答

5

首先,儘量考慮你是否需要實例。如果沒有,則不會涉及同步,因爲您的INSTANCE將在課程加載時初始化。

如果您確實需要懶洋洋地初始化您的實例,然後做使getInstance同步,因爲這會導致所有的線程等待對方無故一旦初始化實例。

如果你要在裏面使用同步塊,你需要仔細檢查空(在同步塊的外部和內部)以確保你最終只有一個實例;另外,你需要你的實例是volatile

最佳實踐方法是在加載時初始化單例實例(但僅在調用容器類的getInstance()時加載)的私有嵌套類SingletonHolder

但是,如果您不需要惰性實例化,最好的做法是使用帶有一個常量的枚舉。


長話短說,我想你會在這裏找到一切:http://en.wikipedia.org/wiki/Singleton_pattern

+0

雙檢查鎖定不是一個解決方案,請參閱:http://www.ibm.com/developerworks/java/library/j-dcl/index.html。在類加載時的初始化對於「util」單例是好的。它可能很難,如果它需要數據庫連接或類似的東西。嘗試對使用這種單例的代碼進行單元測試。 –

+0

@Piotr:從這篇文章中:「編者注:這篇文章在Java 5.0修訂之前引用了Java Memory Model;關於內存排序的陳述可能不再正確。」 Java 5.0中的新內存模型修復了這些問題,'volatile'現在是可靠的。 –

+0

那太好了。我忽略了這一點。 – nullpotent

2

鑑於singleton通常被認爲是反模式,我會質疑爲什麼你想要它。

這種模式使得單元測試更加困難[6],因爲它將全局狀態引入到應用程序中。還應注意到 該模式降低了程序內並行的可能性,因爲在多線程上下文 中的單例訪問必須被序列化,例如通過鎖定。依賴注入 的擁護者會如果有可能認爲這是一個反模式,主要是由於它的私有與靜態方法

使用 我會嘗試使用dependency injection來解決上述問題。

+0

反模式,我吐了他們 – nullpotent

2

閱讀Item 3Effective javaenforce singleton with property with private constructed or an enum type

3

我更喜歡使用enum,因爲它更簡單,仍然是線程安全的,並延遲加載。

enum Singleton { 
    INSTANCE; 
} 

我不會讓它變得比它需要更復雜。