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

饿汉式

实现思路:在类加载时就创建单例实例,由于类加载由 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;
    }
}
相关推荐
刀法如飞6 分钟前
Go数组去重的20种实现方式,AI时代解决问题的不同思路
后端·算法·go
AI人工智能+电脑小能手33 分钟前
【大白话说Java面试题】【Java基础篇】第30题:JDK动态代理和CGLIB动态代理有什么区别
java·开发语言·后端·面试·代理模式
swipe44 分钟前
别再把 AI 聊天做成纯文本:从 agui 这个前后端项目,拆解“可感知工具调用”的流式 AI UI
后端·langchain·llm
GetcharZp1 小时前
GitHub 爆火!纯 Go 编写的文件同步神器 Syncthing,凭什么成为程序员的标配?
后端
hERS EOUS1 小时前
SpringBoot 使用 spring.profiles.active 来区分不同环境配置
spring boot·后端·spring
LucianaiB1 小时前
我用飞书多维表做了一个 AI 活动推荐智能体:每天自动催我别错过截止日期!
后端
头发够用的程序员1 小时前
C++和Python面试经典算法汇总(一)
开发语言·c++·python·算法·容器·面试
铁皮饭盒2 小时前
第2课:5分钟!用 Trae AI 生成你的第一个后端服务(Bunjs + Elysia)
前端·后端·全栈
金銀銅鐵2 小时前
[git] 浅解 git reset 命令
git·后端