饿汉式
实现思路:在类加载时就创建单例实例,由于类加载由 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;
}
}