全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-11 6 分钟 ✍️ juanwangdev

Java单例模式

单例模式保证一个类只有一个实例,并提供全局访问点。

模式定义

意图:确保类只有一个实例,自行创建并提供全局访问。

适用场景

  • 配置管理器
  • 日志记录器
  • 数据库连接池
  • 缓存管理器

实现方式

1. 饿汉式(推荐)

Java
public class Singleton {
    // 类加载时就创建实例
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}  // 私有构造器

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

优点:实现简单、线程安全 缺点:类加载时就初始化,可能浪费资源

2. 懒汉式(不推荐)

Java
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();  // 线程不安全!
        }
        return instance;
    }
}

问题:多线程环境下可能创建多个实例

3. 同步方法懒汉式

Java
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

优点:线程安全 缺点:每次调用都同步,性能差

4. 双重检查锁(DCL)

Java
public class Singleton {
    private volatile static Singleton instance;  // volatile很重要

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {                      // 第一次检查
            synchronized (Singleton.class) {
                if (instance == null) {              // 第二次检查
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

volatile作用:防止指令重排序,保证instance初始化完成后再返回。

5. 静态内部类(推荐)

Java
public class Singleton {
    private Singleton() {}

    // 静态内部类,延迟加载
    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

优点:线程安全、延迟加载、无同步开销

6. 枚举(最佳方案)

Java
public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("单例方法");
    }
}

// 使用
Singleton.INSTANCE.doSomething();

优点

  • 线程安全
  • 防止反射破坏
  • 防止序列化破坏
  • 代码简洁

各实现方式对比

方式线程安全延迟加载性能防反射防序列化
饿汉式
懒汉式
同步方法
双重检查
静态内部类
枚举

防止反射破坏

Java
public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {
        // 防止反射创建实例
        if (INSTANCE != null) {
            throw new IllegalStateException("单例已存在");
        }
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

防止序列化破坏

Java
public class Singleton implements Serializable {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }

    // 反序列化时返回已有实例
    protected Object readResolve() {
        return INSTANCE;
    }
}

实际应用示例

Java
// 配置管理器
public class ConfigManager {
    private static final ConfigManager INSTANCE = new ConfigManager();
    private Properties config = new Properties();

    private ConfigManager() {
        loadConfig();
    }

    public static ConfigManager getInstance() {
        return INSTANCE;
    }

    public String get(String key) {
        return config.getProperty(key);
    }

    private void loadConfig() {
        try {
            config.load(new FileInputStream("config.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

注意事项

私有构造器防止外部实例化

volatile 保证DCL的正确性

枚举是最安全、最简洁的实现

考虑序列化和反射攻击的防御

单例不适合需要继承的场景

要点总结

  1. 单例确保类只有一个实例,提供全局访问
  2. 饿汉式简单安全,静态内部类延迟加载
  3. 双重检查锁需配合volatile使用
  4. 枚举是最推荐的实现方式,防反射防序列化
  5. 私有构造器是单例的基础

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java代理模式
下一篇 → Java原型模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库