單例模式確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例單例模式。單例模式只應在有真正的「單一實例」的需求時纔可以使用。
java
如:俺有 6 個帥氣的老公,她們的老婆都是我,我就是咱們家裏的老婆Sigleton,她們只要說道「老婆」,都是指的同一我的,那就是我(剛纔作了個夢啦,哪有這麼好的事)
chrome
1,單例類只能有一個實例。
2,單例類必須本身建立本身的惟一實例。
3,單例類必須給全部其餘對象提供這一實例。安全
1,餓漢式網絡
餓漢式在類建立的同時就已經建立了一個靜態的對象供系統使用,之後就再也不改變。多線程
//餓漢式單例類.在類初始化時,已經自行實例化 public class Singleton1 { private Singleton1() {} private static final Singleton1 single = new Singleton1(); //靜態工廠方法 public static Singleton1 getInstance() { return single; } }
2,懶漢式1,非線程安全併發
懶漢式在類建立的時候沒有建立了對象,只是進行聲明,在用戶調用getInstance方法的時候才進行建立。app
//懶漢式單例類.在第一次調用的時候實例化本身 public class Singleton { private Singleton() {} private static Singleton single=null; //靜態工廠方法 public static Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; } }
以上懶漢式單利實現沒有考慮線程安全問題,併發環境可能出現多個Singleton實例,要實現線程安全,須要對getInstance進行改造。性能
2,懶漢式2,給getInstance加上同步spa
public static synchronized Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }
2,懶漢式3,給getInstance加上雙重檢查鎖定線程
public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }
2,懶漢式4,給getInstance加上靜態內部類
public class Singleton { private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return LazyHolder.INSTANCE; } }
餓漢就是類一旦加載,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,
而懶漢式,只有當調用getInstance的時候,纔回去初始化這個單例。
餓漢式天生就是線程安全的,能夠直接用於多線程而不會出現問題,
懶漢式自己是非線程安全的,爲了實現線程安全有幾種寫法,分別是上面的一、二、3,這三種實如今資源加載和性能方面有些區別。