如何实现一个线程安全的单例模式?

饿汉式

实现思路:在类加载时就创建单例实例,由于类加载由 JVM 保证线程安全,所以天生线程安全。

代码示例(Java):

csharp 复制代码
public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

懒汉式(双重检查锁)

实现思路:只有在第一次调用 getInstance 方法时才创建实例。通过双重检查锁机制,先检查实例是否已存在,若不存在再进行同步操作创建实例,避免了不必要的同步开销。双重检查锁+volatile 解决线程安全问题(防止指令重排的半初始化对象)

代码示例(Java):

csharp 复制代码
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;
    }
}

volatile 关键字在此处很关键,它禁止指令重排序,保证在多线程环境下 instance 的创建过程按预期执行,避免其他线程拿到未初始化完全的实例。

静态内部类方式

实现思路:利用类的加载机制,将单例实例的创建放在静态内部类中。当外部类被加载时,静态内部类不会被加载,只有当调用 getInstance 方法时,静态内部类才会被加载,此时创建单例实例,由于类加载的线程安全性,实现了线程安全的单例

代码示例(Java):

csharp 复制代码
public class Singleton {       
    //静态内部类方式
    private Singeton() {
    }

    private static class singletonHolder {
        static final Singeton instance = new Singeton();
    }

    public static Singeton getInstance() {
        return singletonHolder.instance;
    }
}
相关推荐
xiaoxue..4 分钟前
合并两个升序链表 与 合并k个升序链表
java·javascript·数据结构·链表·面试
忧郁的Mr.Li22 分钟前
SpringBoot中实现多数据源配置
java·spring boot·后端
暮色妖娆丶1 小时前
SpringBoot 启动流程源码分析 ~ 它其实不复杂
spring boot·后端·spring
Coder_Boy_1 小时前
Deeplearning4j+ Spring Boot 电商用户复购预测案例中相关概念
java·人工智能·spring boot·后端·spring
Java后端的Ai之路1 小时前
【Spring全家桶】-一文弄懂Spring Cloud Gateway
java·后端·spring cloud·gateway
野犬寒鸦2 小时前
从零起步学习并发编程 || 第七章:ThreadLocal深层解析及常见问题解决方案
java·服务器·开发语言·jvm·后端·学习
猿小羽2 小时前
AIGC 应用工程师(3-5 年)面试题精讲:从基础到实战的系统备战清单
面试·大模型·aigc·agent·rag
Honmaple2 小时前
OpenClaw 实战经验总结
后端
golang学习记3 小时前
Go 嵌入结构体方法访问全解析:从基础到进阶陷阱
后端
boooooooom3 小时前
Pinia必学4大核心API:$patch/$reset/$subscribe/$onAction,用法封神!
javascript·vue.js·面试