设计模式------单例模式

单例模式(Singleton)的 5 种实现方式及最佳实践
一、懒汉式单例模式(线程安全但性能低,每次获取都加锁,性能差)

public class Singleton {
    private static Singleton instance;
    // 私有构造
    private Singleton() {}
    // 方法同步
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

二、饿汉式单例模式(线程安全但可能造成资源浪费,类加载时就初始化)

public class Singleton {
    // 类加载时立即初始化
    private static final Singleton instance = new Singleton();
    // 私有构造
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

三、双重检查锁(兼顾延迟加载和线程安全,需volatile保证可见性和有序性)

public class Singleton {
    private static volatile Singleton instance;
    // 私有构造
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) { // 第一次检查
            synchronized (Singleton.class) {
                if (instance == null) { // 第二次检查
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

四、静态内部类(推荐方案,线程安全且延迟加载。static 变量是在所属类首次被访问时加载,静态内部类 InnerClass 是一个独立类,它的 static 变量不会因为 Singleton 类加载而初始化,只有调用 getInstance() 时,InnerClass 才会被 JVM 加载,这时 instance 才会被创建)

public class Singleton {
    // 私有构造
    private Singleton() {}
    private static class InnerClass {
        // 只有调用 getInstance() 时才加载 InnerClass
        static final Singleton instance = new Singleton();
    }
    public static Singleton getInstance() {
        return InnerClass.instance;
    }
}

五、枚举(最佳实践,防反射攻击和序列化问题。枚举的每个实例都是 全局唯一 的,由 JVM 在类加载时初始化,且无法通过反射或序列化破坏其唯一性)

public enum Singleton {
    INSTANCE; // 天然单例
    public void doSomething() {
        // 方法实现
    }
}
// 使用:Singleton.INSTANCE.doSomething();

Spring的 @Scope("singleton") 也是类似思想,但由容器管理而非代码控制

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容