設計模式——單例模式

場景

在學習Mybatis或者Hibernate中,有一個SqlSessionFactory對象。此對象屬於重量級對象,消耗的資源比較大,也只需要存在一個即可。類似的對象還有,線程池、緩存、日誌等。這種情況下,就可以使用單例模式來進行控制對象的創建,確保只存在一個。

餓漢模式

懶漢的的單例模式顧名思義就是,在使用前就已經完成的初始化。
代碼:

public class HungrySingleton {

    //類裝載時就完成初始化
    private static HungrySingleton hungrySingleton = new HungrySingleton();

    //申明私有的構造方法,無法外部通過new初始化對象
    private HungrySingleton() {

    }

    public static HungrySingleton getSingleton() {
        System.out.println("獲取單例對象");
        return HungrySingleton.hungrySingleton;
    }
}

這樣的寫法很簡單,但由於在類裝載時就完成了初始化,可能會造成一定的資源浪費,但是不存在多線程的問題,比較常見。

懶漢模式

餓漢模式是在類裝載的時候就完成了初始化,懶漢模式在被調用的時候才進行初始化,不會造成內存的浪費問題。
代碼:

public class LazySingleton {

    private static LazySingleton lazySingleton;

    //申明私有的構造方法,無法外部通過new初始化對象
    private LazySingleton() {

    }

    public static LazySingleton getLazySingleton() {
        //多線程中,可能出現問題,導致多次初始化
        if (lazySingleton == null) {
            System.out.println("完成懶漢加載");
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

在多線程中,一個線程準備創建一個對象,這時另一個線程進入if條件判斷中,此時對象還未創建,兩個線程都將創建對象。

懶漢—Version2.0

public class LazySingleton {

    private static LazySingleton lazySingleton;

    //申明私有的構造方法,無法外部通過new初始化對象
    private LazySingleton() {

    }

    //同步
    public static synchronized LazySingleton getLazySingleton() {
        if (lazySingleton == null) {
            System.out.println("完成懶漢加載");
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

一整個方法加上synchronized 進行同步,對性能而言會存在很大的問題,再進一步改進。

懶漢—Version3.0

public class LazySingleton {

    private static LazySingleton lazySingleton;

    //申明私有的構造方法,無法外部通過new初始化對象
    private LazySingleton() {

    }

    //同步
    public static synchronized LazySingleton getLazySingleton() {
        if (lazySingleton == null) {
            synchronized (LazySingleton.class) {
                if (lazySingleton == null) {
                    System.out.println("完成懶漢加載");
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}

需要對對象進行雙重檢查才能保證在多線程下,不會創建多個對象。

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