深入理解單例模式

單例模式:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

解決的問題:一個全局使用的類,頻繁的創建和銷燬。

1.   餓漢式單例(立即加載)

// 餓漢式單例
public class Singleton1 {
    // 私有構造
    private Singleton1() {}

    private static Singleton1 single = new Singleton1();

    // 靜態工廠方法
    public static Singleton1 getInstance() {
        return single;
    }
}

2.   懶漢式單例(延時加載)

// 懶漢式單例
public class Singleton2 {

    // 私有構造
    private Singleton2() {}

    private static Singleton2 single = null;

    public static Singleton2 getInstance() {
        if(single == null){
            single = new Singleton2();
        }
        return single;
    }
}

餓漢式和懶漢式的區別:

餓漢式是一加載就把單例實例化,而懶漢式是當調用靜態方法getInstance的時候,初始化單例。

餓漢式是線程安全的,懶漢線程不安全。

懶漢式改進:

        方法加鎖或者同步代碼塊加鎖,保證了線程安全,但效率低。每次都要加鎖解鎖。代碼入下

public class Singleton3 {
    // 私有構造
    private Singleton3() {}

    private static Singleton3 single = null;

    public static Singleton3 getInstance() {
        
        // 等同於 synchronized public static Singleton3 getInstance()
        synchronized(Singleton3.class){
          // 注意:裏面的判斷是一定要加的,否則出現線程安全問題
            if(single == null){
                single = new Singleton3();
            }
        }
        return single;
    }
}

 

繼續改進:

      雙重鎖定方法。 先進行判斷,若未被創建時,加鎖。代碼入下

public class Singleton4 {
    // 私有構造
    private Singleton4() {}

    private static Singleton4 single = null;

    // 雙重檢查
    public static Singleton4 getInstance() {
        if (single == null) {
            synchronized (Singleton4.class) {
                if (single == null) {
                    single = new Singleton4();
                }
            }
        }
        return single;
    }
}

當然 ,還可以使用靜態內部類,靜態代碼塊,內部枚舉類等方式

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章