淺談單例模式的實現方式

單例模式(來自菜鳥教程)

單例模式(Singleton Pattern)是Java中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。

單例模式的要求

  • 構造方法必須私有化(確保只有自己能創建)
  • 以靜態方法返回實例(外界不能通過new來獲取到對象)
  • 確保對象實例只有一個(只對類進行一次實例化,以後都直接獲取第一次實例化的對象)

單例模式的實現

1、懶漢式(線程不安全)

描述:這種方式是最基本的實現方式,但是不支持多線程。因爲沒有加鎖,在多線程不能正常工作

//懶漢式(線程不安全)
public class Singleton {  
    private static Singleton instance;  

    private Singleton (){}  
  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

2、懶漢式(線程安全)

描述:能夠在多線程下正常工作,但是,效率極低

//懶漢式(線程安全)
public class Singleton {  
    private static Singleton instance;  

    private Singleton (){}  

    public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

3、雙重校驗鎖(DCL,即double-checked locking)(線程安全)

描述:對懶漢式(線程安全)的優化,採用雙鎖的機制,安全且在多線程情況下能保持高性能

//雙重校驗鎖
public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

4、餓漢式(線程安全)

描述:這種方式比較常用,但容易產生垃圾對象

//餓漢式
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
        return instance;
    }
}

5、靜態內部類(線程安全)

描述:這種方式達到跟雙重校驗鎖一樣的效果,這種方式只適用於靜態域的情況,雙重校驗鎖可在實例域需要延遲初始化時使用

//靜態內部類
public class Singleton {
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    private Singleton() {

    }

    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

6、枚舉(線程安全)

描述:這種方式還沒有被廣泛採用,但是這種實現是單例模式的最佳方法。更簡潔、自動支持序列化機制、絕對防止多次實例化

//枚舉
public enum Singleton {
    INSTANCE;

    public void whateverMethod() {

    }
}

總結

一般情況下,不建議使用第1種和第2種懶漢方式,建議使用第4種餓漢方式。只有在明確實現lazy loading時,纔會使用第5種靜態內部類方式。如果涉及到反序列化創建對象時,可以使用第6種枚舉方式。如果有其他需求,可以考慮使用第3種雙重校驗鎖方式。

PS:開始面臨着春招,好多面經都有說到設計模式。最常見的面試題就是講一講單例模式的實現和理解,所以我寫一下,加深我對單例模式的理解和印象。覺得對你有幫助的話可以點點贊,謝謝啦~~~

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