單身設計模式下應該如何選擇?Singleton,Critical section
1)make whole getInstance() method synchronized
OR
2)make only critical section synchronized.
應該是一個人的方法,爲什麼?
單身設計模式下應該如何選擇?Singleton,Critical section
1)make whole getInstance() method synchronized
OR
2)make only critical section synchronized.
應該是一個人的方法,爲什麼?
首先,儘量考慮你是否需要懶實例。如果沒有,則不會涉及同步,因爲您的INSTANCE
將在課程加載時初始化。
如果您確實需要懶洋洋地初始化您的實例,然後做不使getInstance
同步,因爲這會導致所有的線程等待對方無故一旦初始化實例。
如果你要在裏面使用同步塊,你需要仔細檢查空(在同步塊的外部和內部)以確保你最終只有一個實例;另外,你需要你的實例是volatile
。
最佳實踐方法是在加載時初始化單例實例(但僅在調用容器類的getInstance()
時加載)的私有嵌套類SingletonHolder
。
但是,如果您不需要惰性實例化,最好的做法是使用帶有一個常量的枚舉。
長話短說,我想你會在這裏找到一切:http://en.wikipedia.org/wiki/Singleton_pattern
雙檢查鎖定不是一個解決方案,請參閱:http://www.ibm.com/developerworks/java/library/j-dcl/index.html。在類加載時的初始化對於「util」單例是好的。它可能很難,如果它需要數據庫連接或類似的東西。嘗試對使用這種單例的代碼進行單元測試。 –
@Piotr:從這篇文章中:「編者注:這篇文章在Java 5.0修訂之前引用了Java Memory Model;關於內存排序的陳述可能不再正確。」 Java 5.0中的新內存模型修復了這些問題,'volatile'現在是可靠的。 –
那太好了。我忽略了這一點。 – nullpotent
鑑於singleton通常被認爲是反模式,我會質疑爲什麼你想要它。
這種模式使得單元測試更加困難[6],因爲它將全局狀態引入到應用程序中。還應注意到 該模式降低了程序內並行的可能性,因爲在多線程上下文 中的單例訪問必須被序列化,例如通過鎖定。依賴注入 的擁護者會如果有可能認爲這是一個反模式,主要是由於它的私有與靜態方法
使用 我會嘗試使用dependency injection來解決上述問題。
反模式,我吐了他們 – nullpotent
閱讀Item 3
從Effective java
enforce singleton with property with private constructed or an enum type
最好的解決方法是不使用單都沒有。 如果您需要在多線程環境中使用單例,請使整個getInstance
同步,或者同時使用靜態字段initalized(對於單元測試更糟糕)。
閱讀http://www.ibm.com/developerworks/java/library/j-dcl/index.html
我更喜歡使用enum
,因爲它更簡單,仍然是線程安全的,並延遲加載。
enum Singleton {
INSTANCE;
}
我不會讓它變得比它需要更復雜。
爲什麼'getInstance'應該同步呢? – gkuzmin
+1對於'')' – sp00m
+ 1對於選項1 – hovanessyan