2013-05-11 57 views
0

這就是我總是創建一個線程安全的單例,以便在多線程應用程序中使用它。線程安全單例和內部類解決方案

public class Logger { 

    private Logger() {} 

    private static Logger instance = new Logger(); 

    public static Logger getInstance() { 
     return instance; 
    } 

    public void log(String s) { 
     // Log here 
    } 
} 

今天,我正在研究把我的Java認證和書上我發現這個其他的解決辦法:

public class Logger { 

    private Logger() {} 

    private static Logger instance; 

    private static class LoggerHolder { 
     public static Logger logger = new Logger(); 
    } 

    public static Logger getInstance() { 
     return LoggerHolder.logger; 
    } 

    public void log(String s) { 
     // Log here 
    } 
} 

他們並沒有提及另一個。

有什麼更好?這兩種解決方案有什麼區別?

回答

1

第二個例子不太可能僅僅因爲您訪問了該類而創建了一個實例。相反,你將不得不訪問內部類。對於JDK庫設計人員來說,這種偏執狂水平是有意義的,但在更受控的代碼庫中,它已經超過了頂級的恕我直言。

我更喜歡簡單,並會用這個來代替

public enum MyLogger { 
    INSTANCE; 

    public void log(String s) { 
     // log here 
    } 
} 

我建議強烈反對創建一個名爲Logger類已經有足夠的混亂在這個類可以包括一個內置的許多實現。

0

第二個是懶惰的。如果由於某種奇蹟,程序加載類但從未調用getInstance(),那麼將不會創建可能是昂貴的創建對象的記錄器實例。坦白地說,如果真的需要一個單例(並且使用依賴注入框架,它們幾乎總是不需要的),我更喜歡第一個解決方案,這更易於理解。如果有的話,我很少看到一個單獨的類被加載,但從未用於真正的代碼。