Loading

单例模式的实现方法

一、懒汉式

public class ASingleton {
    private static ASingleton INSTANCE;

    private ASingleton() {}

    /**
     * 懒汉: 延迟初始化, 线程不安全的单例模式
     * @return 对象实例
     */
    public static ASingleton getInstance() {
        if (null == INSTANCE) {
            INSTANCE = new ASingleton();
        }
        return INSTANCE;
    }
}

二、饿汉式

public class BSingleton {
    public static final BSingleton INSTANCE = new BSingleton();

    private BSingleton() {}

    /**
     * 饿汉: 线程安全, 但是可能会增加不必要内存开销, 存在反射破解单例的问题
     * @return 对象实例
     */
    public static BSingleton getInstance() {
        return INSTANCE;
    }
}

三、DCL

public class CDoubleCheckLock {
    private static volatile CDoubleCheckLock INSTANCE;

    private CDoubleCheckLock() {
    }

    /**
     * DCL: 使用锁和 volatile 来实现线程安全懒汉式单例(volatile 来防止指令重排), 缺点是存在反射破解单例的问题
     * @return 对象实例
     */
    public static CDoubleCheckLock getInstance() {
        if (null == INSTANCE) {
            synchronized (CDoubleCheckLock.class) {
                if (null == INSTANCE) {
                    INSTANCE = new CDoubleCheckLock();
                }
            }
        }

        return INSTANCE;
    }
}

四、静态内部类

public class DInnerClass {
    private DInnerClass() {
    }

    /**
     * 静态内部类: 借助类加载机制来实现线程安全的懒汉式单例, 缺点仍然是存在反射破解单例的问题
     * @return 对象实例
     */
    public static DInnerClass getInstance() {
        return InnerClass.INSTANCE;
    }

    private static class InnerClass {
        static final DInnerClass INSTANCE = new DInnerClass();
    }
}

五、枚举

public enum EEnum {
    INSTANCE;

    /**
     * 枚举: 最安全的单例模式, 既不存在线程安全问题, 也不会被序列化、反射所破解
	 * 而且枚举类构造方法的权限修饰符默认是 private, 且只能为 private
     * @return 对象实例
     */
    public static EEnum getInstance() {
        return INSTANCE;
    }
}
posted @ 2021-08-20 10:47  xtyuns  阅读(42)  评论(0编辑  收藏  举报