Java單例模式的各類實現(餓漢、懶漢、靜態內部類、static代碼塊、enum枚舉類型)

餓漢模式

餓漢模式就是當即加載,在方法調用前,實例就已經被建立了,因此是線程安全的。java

public class MyObject1 {
    private static MyObject1 myObject1 = new MyObject1();
    private MyObject1() {}
    public static MyObject1 getInstance() {
        return myObject1;
    }
}

懶漢模式

懶漢就是延遲化加載,當須要使用的時候才進行實例化。安全

線程不安全

public class MyObject2 {
    private static MyObject2 myObject2;
    private MyObject2() {}
    public static MyObject2 getInstance() {
        if (myObject2 == null) {
            myObject2 = new MyObject2();
        }
        return myObject2;
    }
}

線程安全

線程安全可是效率低下線程

public class MyObject3 {
    private static MyObject3 myObject3;
    private MyObject3() {}
    synchronized public static MyObject3 getInstance() {
        if (myObject3 == null) {
            myObject3 = new MyObject3();
        }
        return myObject3;
    }
}

使用DCL雙檢查鎖,線程安全並且效率獲得提升,只將進行實例化的代碼進行加鎖。code

public class MyObject4 {
    private volatile static MyObject4 myObject4;
    private MyObject4() {}
    public static MyObject4 getInstance() {
        if (myObject4 == null) {
            synchronized (MyObject4.class) {
                if (myObject4 == null) {
                    myObject4 = new MyObject4();
                }
            }
        }
        return myObject4;
    }
}

使用靜態內部類

線程安全,也是一種懶加載模式。
靜態內部類中的靜態成員只在第一次使用的時候加載,所以保證了線程安全。get

public class MyObject5 {
    private static class MyObject5Handle {
        private static MyObject5 myObject5 = new MyObject5();
    }
    private MyObject5() {}
    public static MyObject5 getInstance() {
        return MyObject5Handle.myObject5;
    }
}

使用static代碼塊

因爲static代碼塊中內容在類加載的時候就執行了,所以保證了線程安全。class

public class MyObject6 {
    private static MyObject6 instance = null;
    private MyObject6() {}
    static {
        instance = new MyObject6();
    }
    public static MyObject6 getInstance() {
        return instance;
    }
}

使用enum枚舉

JVM會保證enum不能被反射而且構造器方法只執行一次,所以該單例是線程安全的。效率

public class MyObject7 {
    private enum MyEnumSingleton {
        enumFactory;
        private MyObject7 myObject7;
        private MyEnumSingleton() {
            myObject7 = new MyObject7();
        }
        public MyObject7 getInstance() {
            return myObject7;
        }
    }
    public static MyObject7 getInstance() {
        return MyEnumSingleton.enumFactory.getInstance();
    }
}
相關文章
相關標籤/搜索