五種方法實現Java的Singleton單例模式

一、最簡單的方法是在類加載的時候初始化這個單獨的實例。
首先,定義單例類(沒有特別的,就是起個名字):


1 public class Singleton{
其次,需要定義類變量將單例對象保存下來:


1 private static Singleton instance = new Singleton();
這裏需要注意兩點:


private:除了Singleton類內部,其它地方無法訪問該變量;


static:確保是靜態類變量,這樣可以通過類名來訪問,無須實例;


再次,需要顯式定義構造函數,並將其設置爲private,這樣在Singleton類之外new的話編譯器就會報錯,即使是Singleton的子類也不行:


1 private Singleton() {}
最後,定義單例對象的獲取方法,


1 public static Singleton getInstance() {
2     return instance;
3 }
 


同樣需要注意:


public:這樣外部才能調用;


static:這樣外部才能通過類名來訪問,否則獲取不到單例對象;
************************************************************
************************************************************
二、使用懶加載。在方法一的基礎上,我們需要修改幾處代碼:


首先,靜態類變量應該初始化爲NULL:


1 private static Singleton instance = NULL;
其次,getInstance()方法需要承擔生成實例的任務:


1 public static Singleton getInstance() {
2     if(instance == NULL)
3         instance = new Singleton();
4     return instance;
5 }


*************************************************************
*************************************************************
三、考慮多線程的問題。方法二在多線程情況下仍然有可能產生多個實例,我們需要使用同步來避免多線程問題。
如下,在getInstance()方法前使用synchronized關鍵字:
1 public static synchronized Singleton getInstance() {}




*************************************************************
*************************************************************


四、考慮性能問題。synchronized關鍵字修飾getInstance()方法,會導致所有調用getInstance()方法的線程都要競爭同一把鎖,即使在單例對象已經生成好的情況下。這裏使用double check的方式。另外,還需要注意instance在初始化過程中,可能已經不爲NULL,這樣有可能會導致程序崩潰,因此這裏加了個臨時變量t,確保初始化完成之後再賦值給instance。


複製代碼
public static Singleton getInstance() {
    if (instance == null) {
        synchronized (Singleton.class) {
            if (instance == null){
                Singleton t = new Singleton();
                instance = t;
            }
        }
    }
    return instance;
}


************************************************************
************************************************************


五、更簡化的方法。基於靜態內部類的特性,我們可以利用它的懶加載機制簡化實現:


複製代碼
1 public static Singleton getInstance(){
2     return NestedClass.instance;
3 }

5 private static class NestedClass{
6     private static Singleton instance = new Singleton();
7 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章