2015-04-07 35 views
0

從我的理解中,Singleton是一個類的單個實例,它持續貫穿整個應用程序生命週期。不過,我已經看到了這些系統的一些不同的實現,但我總是被告知他們錯了,有缺陷等等。我將發佈我更常看到的兩個,我希望聽到基於哪個實施更好以及爲什麼的意見/事實。實現是可編譯的。關於單例實現的理解衝突

實現答:

public class Foo { 
    private static Foo singelton; 

    private Foo() { 
     System.out.println("Bar"); 
    } 

    public static Foo getSingleton() { 
     if(singleton == null) singleton = new Foo(); 
     return singleton; 
    } 

    public static void main(String[] args) { 
     Foo.getSingleton(); 
    } 
} 

實現B:

public class Foo { 
    private static final Foo singelton = new Foo(); 

    private Foo() { 
     if(singelton != null) { 
      throw new IllegalStateException("Singleton class was already constructed."); 
     } 
     System.out.println("Bar"); 
    } 

    public static void main(String[] args) { 
     // NOT REQUIRED 
    } 

} 

你會在實現B中的Singleton實例是最後通知。而且,由於靜態實現,方法永遠不需要構造這個類的實例。

執行A和B都會產生相同的結果。

意見?

+1

使用的['Enum'(http://stackoverflow.com/q/26285520/2970947)。 –

+0

實現B應該有一個單身的getter或者爲了清晰而省略了嗎? – PakkuDon

+0

@Pakku - 略去。考慮到這個課程裏面的一切都在完成,我不覺得它對這個問題有所貢獻。 – Hobbyist

回答

1

嘿,你已經展示了兩個實現,第二個被稱爲提前初始化,第一個被稱爲延遲初始化,因爲它只根據需要初始化類。 但是,您的第一次初始化將在多線程環境中失敗。 你必須使用雙重檢查鎖定才能保護你的代碼。 E.例如, :

public class EagerSingleton { 
    private static volatile EagerSingleton instance = null; 

    // private constructor 
    private EagerSingleton() { 
    } 

    public static EagerSingleton getInstance() { 
     if (instance == null) { 
      synchronized (EagerSingleton.class) { 
       // Double check 
       if (instance == null) { 
        instance = new EagerSingleton(); 
       } 
      } 
     } 
     return instance; 
    } 
} 

對於得較多的詳細信息,請查詢: http://howtodoinjava.com/2012/10/22/singleton-design-pattern-in-java/

+0

所以從我的理解(閱讀鏈接之前和之後)。渴望'(早期)'初始化是最好的方法,特別是如果在運行時需要類?它是否正確? – Hobbyist

+0

但如果實例需要更多的內存,那麼它將保持在沒有使用狀態。 –

+0

感謝您的信息。 – Hobbyist