2.1-單例實現方式
餓漢模式
執行緒安全,呼叫效率高,但是不能延時載入
public class SingletonObject1 { private static final SingletonObject1 instance = new SingletonObject1(); private SingletonObject1() {} public static SingletonObject1 getInstance() { return instance; } }
懶漢模式
執行緒不安全,會產生多個例項
public class SingletonObject2 { private static SingletonObject2 instance; private SingletonObject2() {} public static SingletonObject2 getInstance() { if (null == instance) { instance = new SingletonObject2(); } return SingletonObject2.instance; } }
getInstance()方法加鎖(效率低)
public class SingletonObject3 { private static SingletonObject3 instance; private SingletonObject3() {} public synchronized static SingletonObject3 getInstance() { if (null == instance) { instance = new SingletonObject3(); } return SingletonObject3.instance; } }
雙重檢測鎖模式
由於指令重排序問題,偶爾會出現異常,比如構造方法裡面有大量的操作,jvm可能不會等到所有的操作都執行完,才返回例項指標
public class SingletonObject4 { private static SingletonObject4 instance; private SingletonObject4() { } public static SingletonObject4 getInstance() { if (null == instance) { synchronized (SingletonObject4.class) { if (null == instance) { instance = new SingletonObject4(); } } } return SingletonObject4.instance; } }
5、雙重檢測鎖模式2
通過volatile解決【4】的問題,嚴格要求happen before,也就是在執行【讀】操作的時候必須看到完整的【寫】操作
public class SingletonObject5 { private static volatile SingletonObject5 instance; private SingletonObject5() {} public static SingletonObject5 getInstance() { if (null == instance) { synchronized (SingletonObject4.class) { if (null == instance) { instance = new SingletonObject5(); } } } return SingletonObject5.instance; } }
6、靜態內部類
懶載入、執行緒安全、效率高
public class SingletonObject6 { private SingletonObject6() {} private static class InstanceHolder { private final static SingletonObject6 instance = new SingletonObject6(); } public static SingletonObject6 getInstance() { return InstanceHolder.instance; } }
7、列舉
列舉是執行緒安全的,而且只會被裝載一次
public class SingletonObject7 { private SingletonObject7() {} private enum Singleton { INSTANCE; private final SingletonObject7 instance; Singleton() { instance = new SingletonObject7(); } public SingletonObject7 getInstance() { return instance; } } public static SingletonObject7 getInstance() { return Singleton.INSTANCE.getInstance(); }