2016-03-08 72 views
2

我在看電報的信使源代碼,我注意到他們的單例類在它們的getInstance方法中都使用局部變量,就像下面一樣。例如,在他們的Android GitHub repo,對NotificationsController.java類,他們有以下幾點:Singleton - 實例化類的最佳方式

private static volatile NotificationsController Instance = null; 
public static NotificationsController getInstance() { 
    NotificationsController localInstance = Instance; 
    if (localInstance == null) { 
     synchronized (MessagesController.class) { 
      localInstance = Instance; 
      if (localInstance == null) { 
       Instance = localInstance = new NotificationsController(); 
      } 
     } 
    } 
    return localInstance; 
} 

我不完全知道什麼是局部變量「localInstance」存在的目的。任何人都可以解釋「localInstance」var的目的究竟是什麼?如果沒有它,就不能實現,就像在下面的代碼中一樣?

private static volatile NotificationsController Instance = null; 
public static NotificationsController getInstance() { 
    if (Instance == null) { 
     synchronized (MessagesController.class) { 
      if (Instance == null) { 
       Instance = new NotificationsController(); 
      } 
     } 
    } 
    return Instance; 
} 
+1

在你的版本,你也缺少第二個'if'檢查'synchronized'塊內。這意味着構造函數可能會被調用兩次。 – Thilo

+0

對我來說只是看起來不好的代碼。對於初學者單身模式以上是反模式http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons。其次,他們正在同步一個不同類的類對象,如果有其他代碼決定對該對象進行鎖定,則可能導致死鎖,第三,您提出的觀點。 GitHub只有一個主要貢獻者。我會猶豫使用那個庫。 – Samuel

回答

1

這是出於性能原因而完成的。

考慮變量初始化時最常見的情況。寫入的代碼將讀取一次volatile變量並返回值。你的版本會讀兩次。由於易失性讀取帶來輕微的性能成本,因此使用本地變量可能會更快。

因爲在你的情況下,懶惰初始化變量是靜態的,所以最好使用持有者類成語。以this answer爲例。

相關問題