2012-08-12 54 views
1

我想知道在多線程環境下,哪一個在實踐中更好。我明白Singleton作爲枚舉類型在類加載時創建一個實例。除此之外,我沒有看到其他任何重要的東西。有沒有優點和缺點?Enum單身人士與Singleton雙重檢查鎖定

辛格爾頓爲Enum類型:

public enum Singleton { 
     INSTANCE; 
     public void doSomething(){ ... } 
} 

辛格爾頓與double-checked locking

public class Singleton{ 
     private volatile static Singleton instance; 

     private Singleton(){} 
     public static Singleton getInstance(){ 
      if(instance == null){ 
       synchronized(Singleton.class){ 
         if(instance == null){ 
          instance = new Singleton(); 
         } 
       } 
      } 
      return instance; 
     } 

} 
+1

@DmitryBeransky這個版本從1.5開始是安全的,在實踐中是1.4。但即使1.6也面臨着它的報廢。 (如果線程安全,我的意思是安全的,因爲它很安全,不安全,因爲很容易出錯,單身人士可能不安全(當然不明智)。) – 2012-08-12 20:17:23

回答

1

經常在多線程應用中,更簡單,更容易理解的代碼更likley工作。

在我看來,第一個例子是顯着比第二個簡單,那就是關鍵。

使用enum的主要親是它更簡單,更復雜的例子是不合理的。雙重鎖定示例允許您以單元測試的有趣方式更改單例,但是我相信這可以通過另一種方式解決。

0

使用enum創建singleton已獲得人氣爲簡單快捷的方式來做到這一點。

此外,你已經在這裏與雙重檢查鎖定,比較,但也有其他方式,而不使用枚舉。

如:

public class Test{ 

     private static Test uniqueInstance = new Test(); 

     private Test(){} 

     public static Test getInstance(){ 


      return uniqueInstance;  
     } 

} 

但我認爲enum使得相當直接用清潔自我前進的方式爲singleton解釋代碼。

1

單身人士有更多的問題,而不僅僅是一個正確的實施。

人們經常使用單例,所以他們不必傳遞對象,他們應該或他們必須在多個方法中傳遞對象。

有很多例子用於實例化Singleton的jdbc連接。

在您需要此連接的方法中,您可以輕鬆訪問它,因爲它是一個Singleton。

public enum DBConnection { 
    INSTANCE; 
    private Connection connection; 
    public Connection getConnection(){ 
    if(connection == null){ 
     instantiateConnection(); 
    } 
    return connection; 
    } 
} 

DBConnection.INSTANCE.getConnection(); 

訪問它,但很多情況下更好地與依賴注入和普萊框架來做到這一點。以GUICE爲例。

在你的代碼中,你不會對DBConnection.INSTANCE和getConnection()進行調用,而你是Class,會有一個用@Inject註釋的字段DBConnection。而你只是使用它。

@Inject 
private DBConnection dBConnection; 

而該類將被@Singleton註釋爲一個Singleton,並且該框架將確保它是一個單例。

如果你有不同的環境,如測試和生產,你可以讓框架爲每個環境注入不同的對象。