Java 中的单例类(Singleton)应用场景分析

 更新时间:2025年09月29日 10:20:15   作者:总会落叶  
单例类是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点,本文给大家介绍Java中的单例类(Singleton)应用场景分析,感兴趣的朋友跟随小编一起看看吧

Java 中的单例类(Singleton)

单例类是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。

单例模式的核心特点

  1. 唯一实例:类只能创建一个对象实例
  2. 全局访问:提供全局访问点获取该实例
  3. 自行实例化:类自己负责创建自己的实例
  4. 构造器私有:防止外部通过 new 创建实例

单例模式的实现方式

1. 饿汉式(Eager Initialization)

public class EagerSingleton {
    // 类加载时就创建实例
    private static final EagerSingleton instance = new EagerSingleton();
    // 私有构造器
    private EagerSingleton() {
        // 防止反射攻击
        if (instance != null) {
            throw new RuntimeException("单例模式禁止反射创建实例");
        }
    }
    // 全局访问点
    public static EagerSingleton getInstance() {
        return instance;
    }
    public void showMessage() {
        System.out.println("饿汉式单例");
    }
}

优点:简单、线程安全
缺点:如果实例未被使用,会造成内存浪费

2. 懒汉式(Lazy Initialization)

public class LazySingleton {
    private static LazySingleton instance;
    private LazySingleton() {}
    // 线程不安全版本
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

3. 线程安全的懒汉式

public class ThreadSafeSingleton {
    private static volatile ThreadSafeSingleton instance;
    private ThreadSafeSingleton() {}
    // 方法同步(性能较差)
    public static synchronized ThreadSafeSingleton getInstance() {
        if (instance == null) {
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }
}

4. 双重检查锁(Double-Checked Locking)

public class DoubleCheckedSingleton {
    // 使用 volatile 保证可见性和禁止指令重排序
    private static volatile DoubleCheckedSingleton instance;
    private DoubleCheckedSingleton() {}
    public static DoubleCheckedSingleton getInstance() {
        if (instance == null) { // 第一次检查
            synchronized (DoubleCheckedSingleton.class) {
                if (instance == null) { // 第二次检查
                    instance = new DoubleCheckedSingleton();
                }
            }
        }
        return instance;
    }
}

5. 静态内部类(推荐使用)

public class InnerClassSingleton {
    private InnerClassSingleton() {
        // 防止反射攻击
        if (SingletonHolder.INSTANCE != null) {
            throw new RuntimeException("单例模式禁止反射创建实例");
        }
    }
    // 静态内部类在第一次被引用时才会加载
    private static class SingletonHolder {
        private static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
    }
    public static InnerClassSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
    public void showMessage() {
        System.out.println("静态内部类单例");
    }
}

优点:懒加载、线程安全、性能好

6. 枚举单例(最安全的方式)

public enum EnumSingleton {
    INSTANCE;
    public void showMessage() {
        System.out.println("枚举单例");
    }
    // 可以添加其他方法
    public void doSomething() {
        System.out.println("执行某些操作");
    }
}
// 使用方式
EnumSingleton.INSTANCE.showMessage();

优点

  • 绝对防止多次实例化
  • 自动支持序列化机制
  • 防止反射攻击

单例模式的应用场景

// 1. 配置管理器
public class ConfigurationManager {
    private static class Holder {
        static final ConfigurationManager INSTANCE = new ConfigurationManager();
    }
    private Properties config;
    private ConfigurationManager() {
        // 加载配置文件
        config = new Properties();
        try {
            config.load(getClass().getResourceAsStream("/config.properties"));
        } catch (IOException e) {
            throw new RuntimeException("加载配置文件失败", e);
        }
    }
    public static ConfigurationManager getInstance() {
        return Holder.INSTANCE;
    }
    public String getProperty(String key) {
        return config.getProperty(key);
    }
}
// 2. 数据库连接池
public class DatabaseConnectionPool {
    private static final DatabaseConnectionPool instance = new DatabaseConnectionPool();
    private List<Connection> connections;
    private DatabaseConnectionPool() {
        // 初始化连接池
        connections = new ArrayList<>();
        // ... 创建数据库连接
    }
    public static DatabaseConnectionPool getInstance() {
        return instance;
    }
    public Connection getConnection() {
        // 从连接池获取连接
        return connections.isEmpty() ? null : connections.remove(0);
    }
    public void releaseConnection(Connection conn) {
        connections.add(conn);
    }
}
// 3. 日志记录器
public class Logger {
    private static volatile Logger instance;
    private Logger() {
        // 初始化日志系统
    }
    public static Logger getInstance() {
        if (instance == null) {
            synchronized (Logger.class) {
                if (instance == null) {
                    instance = new Logger();
                }
            }
        }
        return instance;
    }
    public void log(String message) {
        System.out.println("[LOG] " + new Date() + ": " + message);
    }
}

单例模式的注意事项

1. 序列化问题

public class SerializableSingleton implements Serializable {
    private static final long serialVersionUID = 1L;
    private static SerializableSingleton instance = new SerializableSingleton();
    private SerializableSingleton() {}
    public static SerializableSingleton getInstance() {
        return instance;
    }
    // 防止反序列化创建新实例
    protected Object readResolve() {
        return getInstance();
    }
}

2. 反射攻击防护

public class ReflectionSafeSingleton {
    private static ReflectionSafeSingleton instance;
    private static boolean initialized = false;
    private ReflectionSafeSingleton() {
        synchronized (ReflectionSafeSingleton.class) {
            if (initialized) {
                throw new RuntimeException("单例模式禁止反射创建实例");
            }
            initialized = true;
        }
    }
    public static ReflectionSafeSingleton getInstance() {
        if (instance == null) {
            synchronized (ReflectionSafeSingleton.class) {
                if (instance == null) {
                    instance = new ReflectionSafeSingleton();
                }
            }
        }
        return instance;
    }
}

3. 克隆防护

public class CloneSafeSingleton implements Cloneable {
    private static final CloneSafeSingleton instance = new CloneSafeSingleton();
    private CloneSafeSingleton() {}
    public static CloneSafeSingleton getInstance() {
        return instance;
    }
    // 防止克隆
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("单例模式禁止克隆");
    }
}

总结

实现方式线程安全懒加载性能推荐度
饿汉式★★★
懒汉式(同步)★★
双重检查锁★★★★
静态内部类★★★★★
枚举★★★★★

最佳实践建议

  • 如果需要懒加载:使用静态内部类方式
  • 如果不需要懒加载:使用枚举方式(最安全)
  • 避免使用简单的懒汉式(线程不安全)
  • 考虑序列化、反射、克隆等安全问题

到此这篇关于Java 中的单例类(Singleton)应用场景分析的文章就介绍到这了,更多相关java单例类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java编程子类能否重写父类的静态方法探索

    Java编程子类能否重写父类的静态方法探索

    关于子类能否重写父类的静态方法,对像我这种初级的编程爱好者来说仍是值得讨论的一件事,下面我们通过具体实例,对此问题进行简单的探索。
    2017-10-10
  • Mac上配置JDK 1.8的超详细流程

    Mac上配置JDK 1.8的超详细流程

    相信每个拿到MAC的小伙伴都是很欣喜的,但是由于MAC系统与WIN系统有着极大的不同,所以使用起来会有一些小困扰,这篇文章主要给大家介绍了关于Mac上配置JDK 1.8的超详细流程,需要的朋友可以参考下
    2023-11-11
  • RabbitMQ安装延迟消息插件的教程(超详细)

    RabbitMQ安装延迟消息插件的教程(超详细)

    RabbitMQ是一个开源的消息队列系统,它支持多种协议和多种语言的客户端,为了处理消息的延迟发送或消费,RabbitMQ本身并不直接提供内置的延迟插件,所以本文给大家介绍了RabbitMQ安装延迟消息插件的教程,需要的朋友可以参考下
    2024-06-06
  • Java线程中synchronized的用法与原理解析

    Java线程中synchronized的用法与原理解析

    这篇文章主要介绍了Java线程中synchronized的用法与原理解析,只要有线程,就会有并发的现象,也同时会产生数据不一致,那么对于需要使用同一个数据的两个线程,就会产生冲突,那么就引出了锁的概念,本篇会针对性的说下synchronized这个关键字,需要的朋友可以参考下
    2024-01-01
  • Java锁机制的使用与实战分析

    Java锁机制的使用与实战分析

    本文全面探讨了Java中的锁机制,包括synchronized关键字、内置锁、显示锁、读写锁、条件变量、乐观锁、悲观锁、自旋锁和StampedLock,每个锁机制都有其特点和适用场景,开发者应根据具体需求选择合适的锁实现,以确保多线程程序的并发安全和性能
    2026-01-01
  • Java实现获取客户端真实IP方法小结

    Java实现获取客户端真实IP方法小结

    本文给大家汇总介绍了2种使用java实现获取客户端真实IP的方法,主要用于获取使用了代理访问的来访者的IP,有需要的小伙伴可以参考下。
    2016-03-03
  • Java中Socket下载一个文本文件

    Java中Socket下载一个文本文件

    这篇文章主要介绍了Socket下载一个文本文件的实例代码,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-06-06
  • java常用工具类之DES和Base64加密解密类

    java常用工具类之DES和Base64加密解密类

    这篇文章主要介绍了java常用工具类之DES和Base64加密解密类,需要的朋友可以参考下
    2014-07-07
  • Java线程实现的三种方式详细解析

    Java线程实现的三种方式详细解析

    这篇文章主要介绍了Java线程实现的三种方式详细解析,Java多线程实现方式主要有三种,继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程,需要的朋友可以参考下
    2023-12-12
  • PowerJob的TransportServiceAware工作流程源码解读

    PowerJob的TransportServiceAware工作流程源码解读

    这篇文章主要介绍了PowerJob的TransportServiceAware工作流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01

最新评论