這裏最近的一個問題有下面的代碼(很好,類似於這個)來實現沒有同步的單例。Java是否有靜態命令初始化失敗?
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
現在,我想明白這是做什麼。由於實例是static final
,因此它在任何線程調用getInstance()
之前就已經建好了,因此不需要同步。
僅當兩個線程同時嘗試呼叫getInstance()
(並且該方法在第一次呼叫而不是在"static final"
時間進行構建時)才需要同步。因此
我的問題基本上是:爲什麼那麼你會永遠喜歡單身的懶建設的東西,如:
public class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
我唯一的想法是,使用static final
方法可能引入排序問題,因爲在C++中的靜態初始化命令失敗。
首先,它的Java實際上有這個問題?我知道訂單內一類是完全指定,但它在某種程度上保證一致的順序類之間(如用類加載器)?其次,如果訂單與一致,那麼爲什麼懶惰施工選擇有利呢?
我認爲延遲初始化的普遍原因是推遲某些東西(可能)昂貴,直到絕對需要,希望它根本不需要。假設您的應用程序想要下載比x更長的內容。用戶可以在x之前關閉它,在這種情況下(通常是昂貴的)連接創建將是浪費。 –
@Michal,如果你在OP中執行一個小型輔助類的加載計算,那麼Java的延遲加載可以讓你獲得延遲初始化的所有好處。如果它不是應該成爲全球的東西w.r.t.一個類加載器,然後這不是一個選項。 –