2026/1/17 21:59:17
网站建设
项目流程
做网站一般会出现的问题,做的网站怎么上传到网上运行,wordpress如何安装插件,厦门哪些企业做视频网站的每日Java面试场景题知识点之-单例模式
一、单例模式概述
单例模式#xff08;Singleton Pattern#xff09;是Java中最简单也是最常用的设计模式之一。它保证一个类只有一个实例#xff0c;并提供一个全局访问点来访问这个实例。在Java企业级项目中#xff0c;单例模式广泛…每日Java面试场景题知识点之-单例模式一、单例模式概述单例模式Singleton Pattern是Java中最简单也是最常用的设计模式之一。它保证一个类只有一个实例并提供一个全局访问点来访问这个实例。在Java企业级项目中单例模式广泛应用于配置管理、数据库连接池、缓存管理等场景。二、单例模式的多种实现方式1. 饿汉式单例模式public class EagerSingleton { // 在类加载时就创建实例线程安全但可能造成资源浪费 private static final EagerSingleton instance new EagerSingleton(); private EagerSingleton() {} public static EagerSingleton getInstance() { return instance; } }特点线程安全类加载时就创建实例可能造成资源浪费2. 懒汉式单例模式线程不安全public class LazySingleton { private static LazySingleton instance; private LazySingleton() {} public static LazySingleton getInstance() { if (instance null) { instance new LazySingleton(); } return instance; } }**问题**在多线程环境下可能创建多个实例。3. 懒汉式单例模式线程安全public class ThreadSafeLazySingleton { private static ThreadSafeLazySingleton instance; private ThreadSafeLazySingleton() {} public static synchronized ThreadSafeLazySingleton getInstance() { if (instance null) { instance new ThreadSafeLazySingleton(); } return instance; } }特点线程安全性能较差每次获取实例都要同步4. 双重检查锁定DCLpublic class DCLSingleton { private static volatile DCLSingleton instance; private DCLSingleton() {} public static DCLSingleton getInstance() { if (instance null) { synchronized (DCLSingleton.class) { if (instance null) { instance new DCLSingleton(); } } } return instance; } }特点线程安全性能较好需要使用volatile关键字防止指令重排序5. 静态内部类方式public class InnerClassSingleton { private InnerClassSingleton() {} private static class SingletonHolder { private static final InnerClassSingleton INSTANCE new InnerClassSingleton(); } public static InnerClassSingleton getInstance() { return SingletonHolder.INSTANCE; } }特点线程安全延迟加载性能最好6. 枚举方式public enum EnumSingleton { INSTANCE; public void doSomething() { // 业务逻辑 } }特点线程安全防止反射攻击防止序列化破坏三、企业级项目中的实际应用场景1. 配置管理器在大型企业应用中配置信息通常需要全局共享且只加载一次。public class ConfigManager { private static volatile ConfigManager instance; private Properties properties; private ConfigManager() { properties new Properties(); loadConfig(); } public static ConfigManager getInstance() { if (instance null) { synchronized (ConfigManager.class) { if (instance null) { instance new ConfigManager(); } } } return instance; } private void loadConfig() { try { properties.load(ConfigManager.class.getClassLoader().getResourceAsStream(config.properties)); } catch (IOException e) { throw new RuntimeException(加载配置文件失败, e); } } public String getProperty(String key) { return properties.getProperty(key); } }2. 数据库连接池数据库连接池是单例模式的典型应用确保全局只有一个连接池实例。public class ConnectionPool { private static volatile ConnectionPool instance; private DataSource dataSource; private ConnectionPool() { initDataSource(); } public static ConnectionPool getInstance() { if (instance null) { synchronized (ConnectionPool.class) { if (instance null) { instance new ConnectionPool(); } } } return instance; } private void initDataSource() { HikariConfig config new HikariConfig(); config.setJdbcUrl(jdbc:mysql://localhost:3306/mydb); config.setUsername(root); config.setPassword(password); config.setMaximumPoolSize(20); dataSource new HikariDataSource(config); } public Connection getConnection() throws SQLException { return dataSource.getConnection(); } }3. 缓存管理器在电商系统中缓存管理器通常需要全局唯一实例。public class CacheManager { private static volatile CacheManager instance; private CacheString, Object cache; private CacheManager() { cache Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(10, TimeUnit.MINUTES) .build(); } public static CacheManager getInstance() { if (instance null) { synchronized (CacheManager.class) { if (instance null) { instance new CacheManager(); } } } return instance; } public void put(String key, Object value) { cache.put(key, value); } public Object get(String key) { return cache.getIfPresent(key); } public void remove(String key) { cache.invalidate(key); } }四、常见问题及解决方案1. 线程安全问题**问题**在多线程环境下单例模式可能创建多个实例。解决方案使用synchronized关键字使用双重检查锁定DCL使用静态内部类使用枚举2. 反射攻击问题**问题**通过反射可以破坏单例模式。解决方案private Singleton() { if (instance ! null) { throw new RuntimeException(单例模式不允许反射创建实例); } }3. 序列化破坏问题**问题**通过序列化和反序列化可以破坏单例模式。解决方案protected Object readResolve() { return getInstance(); }4. 性能问题**问题**同步方法会影响性能。解决方案使用双重检查锁定使用静态内部类使用枚举五、最佳实践选择合适的实现方式根据具体场景选择最适合的单例实现方式考虑线程安全在多线程环境中必须保证线程安全防止反射和序列化破坏对于重要的单例类需要防止反射和序列化破坏考虑资源管理确保单例类能够正确管理资源避免过度使用单例模式虽然方便但过度使用会导致代码耦合度高六、总结单例模式是Java企业级开发中的重要设计模式它保证一个类只有一个实例并提供全局访问点。在实际项目中我们需要根据具体场景选择合适的实现方式并注意线程安全、反射攻击、序列化破坏等问题。掌握单例模式对于Java开发者来说是非常重要的它不仅能够帮助我们写出更好的代码还能够在面试中展示我们的设计能力。感谢读者观看