在Java中实现单例模式有多种方法,每种方法在线程安全、性能和初始化时机上有所不同。以下是常见的实现方式及其特点:
特点:类加载时立即初始化,线程安全但可能浪费资源。
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {} // 私有构造
public static Singleton getInstance() {
return INSTANCE;
}
}
优势:简单、线程安全。 缺点:即使未使用也会创建实例,占用内存。
特点:延迟初始化,但非线程安全。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // 多线程下可能重复创建
}
return instance;
}
}
改进(同步方法):
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
缺点:同步方法性能较差。
特点:延迟初始化 + 线程安全 + 高效。
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
防止指令重排序(避免半初始化对象)。特点:延迟加载 + 线程安全 + 无同步开销。
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
原理:利用类加载机制保证线程安全,Holder
类仅在调用getInstance()
时加载。
特点:最简洁的线程安全实现,防止反射攻击。
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
优势:
特点:线程内单例,不同线程不同实例。
public class ThreadLocalSingleton {
private static final ThreadLocal<ThreadLocalSingleton> instance =
ThreadLocal.withInitial(ThreadLocalSingleton::new);
private ThreadLocalSingleton() {}
public static ThreadLocalSingleton getInstance() {
return instance.get();
}
}
应用场景:需要线程隔离的单例(如数据库连接)。
readResolve()
方法返回现有实例。volatile
(如双重检查锁)。ThreadLocal
(线程隔离)、双重检查锁(高性能延迟加载)。