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();
    }
}
相关文章
相关标签/搜索