侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

单例模式在Java中的实现与应用

2025-12-12 / 0 评论 / 4 阅读

题目

单例模式在Java中的实现与应用

信息

  • 类型:问答
  • 难度:⭐

考点

单例模式概念,线程安全实现,应用场景

快速回答

单例模式确保一个类只有一个实例,并提供全局访问点。线程安全实现要点:

  • 私有化构造方法
  • 静态私有成员变量保存实例
  • 静态工厂方法获取实例
  • 使用双重检查锁定(Double-Checked Locking)保证线程安全

示例代码:

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;
    }
}
## 解析

1. 单例模式原理

单例模式(Singleton Pattern)属于创建型设计模式,核心思想是:

  • 确保类只有一个实例存在
  • 提供全局访问点(通常为静态方法)
  • 自行创建实例(私有构造器)

设计意图:当系统需要全局唯一对象时(如配置管理器、线程池、数据库连接池),避免重复创建消耗资源。

2. 线程安全实现(双重检查锁定)

完整代码示例:

public class DatabaseConnection {
    // volatile保证可见性和禁止指令重排序
    private static volatile DatabaseConnection instance;

    // 私有构造器阻止外部实例化
    private DatabaseConnection() {
        // 初始化数据库连接
    }

    public static DatabaseConnection getInstance() {
        // 第一次检查:避免不必要的同步
        if (instance == null) {
            synchronized (DatabaseConnection.class) {
                // 第二次检查:确保只有一个线程创建实例
                if (instance == null) {
                    instance = new DatabaseConnection();
                }
            }
        }
        return instance;
    }

    // 示例方法
    public void executeQuery(String sql) {
        System.out.println("Executing: " + sql);
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        DatabaseConnection conn1 = DatabaseConnection.getInstance();
        DatabaseConnection conn2 = DatabaseConnection.getInstance();

        System.out.println(conn1 == conn2); // 输出 true
        conn1.executeQuery("SELECT * FROM users");
    }
}

3. 关键点说明

  • volatile关键字:防止JVM指令重排序,确保其他线程看到完全初始化的对象
  • 双重检查:外层判断避免每次调用都同步,内层判断防止多次实例化
  • 私有构造器:彻底阻止通过new关键字创建实例

4. 最佳实践

  • 枚举实现(推荐):Java枚举天然支持单例,绝对防止反射攻击
    public enum EnumSingleton {
        INSTANCE;
        public void doSomething() { /*...*/ }
    }
  • 静态内部类:利用类加载机制保证线程安全
    public class Singleton {
        private Singleton() {}
        private static class Holder {
            static final Singleton INSTANCE = new Singleton();
        }
        public static Singleton getInstance() {
            return Holder.INSTANCE;
        }
    }

5. 常见错误

错误实现问题修复方案
未加锁的懒汉式多线程下可能创建多个实例添加同步控制
直接在方法上加锁每次访问都同步,性能差改用双重检查
缺少volatile可能返回未完全初始化的对象声明变量为volatile

6. 应用场景

  • 配置信息管理器(全局唯一配置)
  • 日志记录器(避免日志文件冲突)
  • 数据库连接池(复用连接资源)
  • Spring默认Bean作用域(单例Bean)

7. 扩展知识

  • 破坏单例的方式:反射、序列化/反序列化
  • 防护措施:枚举实现、重写readResolve()方法
  • 与静态工具类的区别:单例可以有状态且支持接口继承