本文目录导读:
我来详细介绍单例模式的几种常见实现方式,每种都有其适用场景和特点。
饿汉式(线程安全)
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 class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点: 线程安全 缺点: 每次调用都同步,性能开销大
双重检查锁定(DCL)
public class Singleton {
// volatile关键字防止指令重排序
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;
}
}
优点: 线程安全,延迟加载,性能好 缺点: 实现较复杂
静态内部类
public class Singleton {
private Singleton() {}
// 静态内部类只有在使用时才会加载
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
优点: 线程安全,延迟加载,实现简单 推荐使用: 这是最常用的实现方式
枚举实现
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
优点:
- 线程安全
- 防止反序列化创建新实例
- 防止反射攻击
- 实现最简单
推荐使用: 这是《Effective Java》推荐的最佳方式
完整示例:枚举方式
// 定义枚举单例
public enum DatabaseConnectionPool {
INSTANCE;
private ConnectionPool pool;
DatabaseConnectionPool() {
// 初始化连接池
pool = new ConnectionPool(10);
}
public Connection getConnection() {
return pool.getConnection();
}
// 使用示例
public static void main(String[] args) {
Connection conn = DatabaseConnectionPool.INSTANCE.getConnection();
// 使用连接...
}
}
防止反射攻击
对于非枚举实现,需要防止反射攻击:
public class Singleton {
private static volatile Singleton instance;
private static boolean initialized = false;
private Singleton() {
if (initialized) {
throw new RuntimeException("单例模式禁止反射创建实例");
}
initialized = true;
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
选择建议
| 场景 | 推荐方式 |
|---|---|
| 简单场景,不介意加载时创建 | 饿汉式 |
| 需要延迟加载 | 静态内部类 |
| 防止反射/序列化破坏 | 枚举 |
| 性能要求高 | DCL或静态内部类 |
最佳实践: 如果你不需要特殊需求,枚举方式是最简单、最安全的单例实现方式。
标签: 饿汉式