所謂單例,就是整個程序有且僅有一個實例。該類負責建立本身的對象,同時確保只有一個對象被建立。 java
單例模式是設計模式裏使用的最多的一種模式之一,只要你想讓對象在程序中有且只有一份,就能夠使用單例模式。設計模式
單例模式使用場景多,可是寫法卻比較考究,據我所知就有五種寫法。安全
// 餓漢模式 // 線程不安全,多線程下可能會出現多個instance對象 public class Singleton1 { private static Singleton1 instance; private Singleton1() { } public static Singleton1 getInstance() { if (instance == null) { instance = new Singleton1(); } return instance; } }
// 餓漢式 // 無論是否有用到,都會在程序啓動時創建對象,若是對象比較大則會浪費空間。 public class Singleton2 { private static Singleton2 instance = new Singleton2(); private Singleton2() { } public static Singleton2 getInstance() { return instance; } }
// 雙檢索 // 解決了懶漢式和餓漢式的缺陷 // 寫法繁瑣些 public class Singleton3 { private volatile static Singleton3 instance; public Singleton3() { } public static Singleton3 getInstance() { if (instance == null) { synchronized (Singleton3.class) { if (instance == null) { instance = new Singleton3(); } } } return instance; } }
// 靜態內部類式 // 這樣不使用這個內部類SingletonHolder // 那麼jvm虛擬機他就不會去加載這個類 public class Singleton4 { private static class SingletonHolder { private static final Singleton4 INSTANCE = new Singleton4(); } private Singleton4() { } public static Singleton4 getInstance() { return SingletonHolder.INSTANCE; } }
// 枚舉式 // 比較推薦的寫法,能夠應對屢次序列化和反射攻擊 public enum Singleton5 { INSTANCE; public static Singleton5 getInstance() { return INSTANCE; } }
單例模式定義和使用場景很簡單,就是爲了保證內存中只有一個對象。下面總結了單例的幾種寫法的優缺點:多線程
序號 | 名稱 | 優勢 | 缺點 |
1 | 懶漢式 | 簡單 | 線程不安全,存在反序列化攻擊和反射攻擊 |
2 | 餓漢式 | 簡單 | 沒有延遲加載,有可能浪費空間,存在反序列化攻擊和反射攻擊 |
3 | 雙檢索式 | 線程安全 | 寫法複雜,存在反序列化攻擊和反射攻擊 |
4 | 靜態內部類式 | 比雙檢索簡單 | 存在反序列化攻擊和反射攻擊 |
5 | 枚舉式 | 簡單、線程安全、能夠防止反序列化攻擊和反射攻擊 | / |
以上就是我對單例模式的一些理解,有不足之處請你們指出,謝謝。jvm