單例模式(來自菜鳥教程)
單例模式(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:開始面臨着春招,好多面經都有說到設計模式。最常見的面試題就是講一講單例模式的實現和理解,所以我寫一下,加深我對單例模式的理解和印象。覺得對你有幫助的話可以點點贊,謝謝啦~~~