Java設計模式之單例設計模式


單例設計模式是一個確保一個類只有一個實例對象,它保證了全局對象的唯一性。
特點:

  1. 一個類只有一個實例。
  2. 一個類自己創建自己的實例。
  3. 一個類需給其他類提供這一個實例(提供的這個類的方法必須是靜態的)。

單例模式分爲懶漢式惡漢式兩種。
惡漢式: 在程序啓動或單例模式類被加載的時候,單例模式實例就已經被創建。(我的理解是:一上來就創建的是惡漢式
懶漢式: 當程序第一次訪問纔會創建單例模式的示例。(我的理解是:使用時纔會創建的是懶漢式

步驟:

  1. 將該類的構造方法定義爲私有方法,這樣其他處的代碼就無法通過調用該類的構造方法來實例化該類的對象,只有通過該類提供的靜態方法來得到該類的唯一實例;
  2. 在該類內提供一個可見的靜態方法,當我們調用這個方法時,如果類持有的引用不爲空就返回這個引用,如果類保持的引用爲空就創建該類的實例並將實例的引用賦予該類保持的引用。

1. 餓漢式單例模式

/**
 * 餓漢式單例模式:一上來就創建實例
 */
public class ESingleton {
    // 1. 構造方法私有化,這樣其他類創建不了該類的示例對象,保證了全局對象的唯一性
    private ESingleton(){}
    // 2. 產生一個唯一的對象,通過類名調用,在類加載之前就已經創建好了
    private static final ESingleton singleton = new ESingleton();

    // 3. 給外部類提供獲取該實例的方法
    // 因爲外部類只能通過對象調用普通方法,但是外部類不能創建對象,所以該方法應設立爲靜態方法,通過類名調用
    public static ESingleton getInstance(){
        return singleton;
    }
}

測試代碼:

public class TestDemo {
    public static void main(String[] args) {
        // 獲得實例
        ESingleton singleton1 = ESingleton.getInstance();
        ESingleton singleton2 = ESingleton.getInstance();

        // == 比較的的兩個對象的地址
        if(singleton1 == singleton2){
            System.out.println("true");
        }
        else{
            System.out.println("false");
        }
    }
}

運行結果:
在這裏插入圖片描述

2. 懶漢式單例模式

/**
 * 懶漢式單例模式:使用時纔會創建
 */
public class LSingleton {
    // 1. 構造方法私有化
    private LSingleton(){}
    // 2. 創建引用
    private static LSingleton singleton = null;
    // 3. 提供外部接口
    public static LSingleton getInstance(){
        if(singleton == null){
            singleton = new LSingleton();
        }
        return singleton;
    }
}

測試代碼:

public class TestLSingleton {
    public static void main(String[] args) {
        LSingleton singleton1 = LSingleton.getInstance();
        LSingleton singleton2 = LSingleton.getInstance();

        if(singleton1 == singleton2){
            System.out.println("true");
        }else{
            System.out.println("false");
        }
    }
}

運行結果:
在這裏插入圖片描述
餓漢式單例模式是一上來就創建對象,所以在類加載是就已經創建好了,且只對外部只有獲得接口,所以餓漢式單例模式是線程安全的。
懶漢式單例模式是使用時纔會創建對象,所以在多線程模式下,當一個線程進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另一個線程也通過了這個判斷語句,這時便會產生多個實例。因此在多線程下,會出現線程安全問題,所以有了下面的Double-Check。

3. 懶漢式單例模式:Double-Check

Double-Check概念對於多線程開發者來說不會陌生,我們進行了兩次if (singleton==null)檢查,這樣就可以保證線程安全了。這樣,實例化代碼只用執行一次,後面再次訪問時,判斷if (singleton==null),直接return實例化對象。

/**
 * 懶漢式單例模式:雙重檢查
 */
public class LYSingleton {
    // 1. 構造方法私有化
    private LYSingleton(){}
    // 2. 創建引用
    private static volitle LYSingleton singleton = null;
    // 3. 提供外部接口
    public static LYSingleton getInstance(){
        if(singleton == null){
            synchronized (LYSingleton.class){
                if(singleton == null){
                    singleton = new LYSingleton();
                }
            }
        }
        return singleton;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章