java中常用的单例模式

转载自:https://blog.csdn.net/qq_38584967/article/details/88910479

设计模式名称 属性
懒汉式单例模式 线程安全,调用效率不高,但是可以延时加载。
饿汉式单例模式 线程安全,调用效率高,但是不是延时加载。
静态内部类实现单例模式(推荐): 线程安全,调用效率高,并且可以延时加载。
枚举实现单例模式 (推荐): 线程安全,调用效率高,不延时加载,防反射和反序列化漏洞。
双重检测得单例模式 线程安全,调用效率不高,用来防止缓存击穿

懒汉式单例模式: 线程安全,调用效率不高,但是可以延时加载。

/**
 * 懒汉式,先不创建实例,等到需要时在创建。
 * 多线程情况下并发效率低。
 * 结论:线程安全,调用效率不高,但是可以延时加载。
 */
public class LazySingleton {
    /**
     * 静态实例变量
     */
    private static LazySingleton instance;

    /**
     * 私有构造函数
     */
    private LazySingleton() {
    }

    /**
     *懒汉式创建实例,需要同步处理
     * @return
     */
    public static synchronized LazySingleton getInstance(){
        if (instance == null){
            instance = new LazySingleton();
        }
        return instance;
    }
}

饿汉式单例模式: 线程安全,调用效率高,但是不是延时加载。

/**
 * 饿汉式,类初始化时立即加载这个对象,
 * 如果加载这个对象耗时间长并且这个对象没有被使用,得不偿失。
 * 结论:线程安全,调用效率高,但是不是延时加载。
 */
public class HungrySingleton {
    /**
     * 静态实例对象
     */
    private static HungrySingleton instance = new HungrySingleton();

    /**
     * 私有的构造函数
     */
    private HungrySingleton() {
    }
    
    /**
     * 静态方法并不需要做同步处理
     * @return
     */
    public static HungrySingleton getInstance(){
        return instance;
    }
    
}

静态内部类实现单例模式(推荐): 线程安全,调用效率高,并且可以延时加载。

/**
 * 静态内部类实现单例模式(懒加载的一种)
 * 静态内部类只有在调用的时候才初始化,并且初始化过程线程安全。
 * instance不提供修改实例方法,静态变量只初始化一次,所以final修饰不加也一样。
 * 兼备了并发高效调用和懒加载的优势。
 * 结论:线程安全,调用效率高,并且可以延时加载。
 */
public class StaticClassSingleton {
    //私有构造函数
    private StaticClassSingleton(){};

    //静态内部类
    private static class SingletonClassInstance{
        private static final StaticClassSingleton INSTANCE =
                new StaticClassSingleton();
    }

    //提供实例的调用方法
    public static StaticClassSingleton getInstance(){
        return SingletonClassInstance.INSTANCE;
    }
}

枚举实现单例模式 (推荐): 线程安全,调用效率高,但是不是延时加载,天然防止反射和反序列化漏洞。

/**
 * 枚举类对象本身就是一个单例对象。
 * 没有延时加载的特性。
 * 可以天然的防止反射和反序列化的漏洞,因为枚举是基于JVM底层实现的。
 * 结论:线程安全,调用效率高,但是不是延时加载,天然防止反射和反序列化漏洞。
 */
public enum  EnumSingleton {
    /**
     * 枚举对象
     */
    INSTANCE;

    /**
     * 成员方法
     */
    public void singletonOperation(){
        //单例对象的其它操作实现。
    }
}

双重检测得单例模式(不建议使用)

/**
 * 懒汉式实现的一种
 * 但是由于编译器优化的原因和JVM底层内部模型原因,偶尔会出现问题
 * 结论:不建议使用。
 */
public class DoubleCheckLocking {
    /**
     * 懒汉式,加上volatile,因为线程创建对象有三步
     * 1、new开辟空间 //2、构造 初始化对象信息 //3、返回对象的地址给引用
     * volatile防止指令重排序,导致2步骤没执行完3步骤便返回的引用。
     */
    private static volatile DoubleCheckLocking instance;
    
    /**
     * 私有的构造函数
     */
    private DoubleCheckLocking(){
    }
    
    /**
     * 双重检测的单例模式
     * @return
     */
    public static DoubleCheckLocking getInstance() {
        //非空返回,不走同步块,提高效率
        if (null == instance) {
            synchronized (DoubleCheckLocking.class) {
                if (null == instance) {
                    instance = new DoubleCheckLocking();
                }
            }
        }
        return instance;
    }
}

 

原文地址:https://www.cnblogs.com/gjq1126-web/p/14200023.html