第134集单例实例模式来处理所有请求Java实战
|字数总计:4.3k|阅读时长:19分钟|阅读量:
1. 单例模式概述
单例模式(Singleton Pattern)是设计模式中最简单也是最常用的模式之一。它确保一个类只有一个实例,并提供一个全局访问点。在Java应用中,单例模式常用于处理所有请求,如配置管理、连接池、缓存管理等场景。本文将详细介绍单例模式的各种实现方式及其在Java实战中的应用。
1.1 核心特点
- 唯一实例: 确保类只有一个实例
- 全局访问: 提供全局访问点
- 线程安全: 在多线程环境下保证实例唯一性
- 延迟加载: 支持懒加载和饿汉式加载
- 性能优化: 减少对象创建开销
1.2 应用场景
- 配置管理器: 系统配置信息管理
- 数据库连接池: 数据库连接管理
- 缓存管理器: 缓存数据管理
- 日志管理器: 日志记录管理
- 线程池管理器: 线程资源管理
2. 单例模式实现
2.1 饿汉式单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
public class EagerSingleton { private static final EagerSingleton INSTANCE = new EagerSingleton(); private EagerSingleton() { System.out.println("EagerSingleton实例被创建"); }
public static EagerSingleton getInstance() { return INSTANCE; }
public void doSomething() { System.out.println("EagerSingleton正在处理业务逻辑"); }
private Object readResolve() { return INSTANCE; } }
|
2.2 懒汉式单例(非线程安全)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public class LazySingleton { private static LazySingleton instance; private LazySingleton() { System.out.println("LazySingleton实例被创建"); }
public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; }
public void doSomething() { System.out.println("LazySingleton正在处理业务逻辑"); } }
|
2.3 懒汉式单例(线程安全)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class ThreadSafeLazySingleton { private static ThreadSafeLazySingleton instance; private ThreadSafeLazySingleton() { System.out.println("ThreadSafeLazySingleton实例被创建"); }
public static synchronized ThreadSafeLazySingleton getInstance() { if (instance == null) { instance = new ThreadSafeLazySingleton(); } return instance; }
public void doSomething() { System.out.println("ThreadSafeLazySingleton正在处理业务逻辑"); } }
|
2.4 双重检查锁定单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
public class DoubleCheckedLockingSingleton { private static volatile DoubleCheckedLockingSingleton instance; private DoubleCheckedLockingSingleton() { System.out.println("DoubleCheckedLockingSingleton实例被创建"); }
public static DoubleCheckedLockingSingleton getInstance() { if (instance == null) { synchronized (DoubleCheckedLockingSingleton.class) { if (instance == null) { instance = new DoubleCheckedLockingSingleton(); } } } return instance; }
public void doSomething() { System.out.println("DoubleCheckedLockingSingleton正在处理业务逻辑"); } }
|
2.5 静态内部类单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public class StaticInnerClassSingleton { private StaticInnerClassSingleton() { System.out.println("StaticInnerClassSingleton实例被创建"); }
private static class SingletonHolder { private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton(); }
public static StaticInnerClassSingleton getInstance() { return SingletonHolder.INSTANCE; }
public void doSomething() { System.out.println("StaticInnerClassSingleton正在处理业务逻辑"); } }
|
2.6 枚举单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public enum EnumSingleton { INSTANCE;
public void doSomething() { System.out.println("EnumSingleton正在处理业务逻辑"); }
public static EnumSingleton getInstance() { return INSTANCE; } }
|
3. Web应用中的单例模式实战
3.1 配置管理器单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
public class ConfigManager { private static volatile ConfigManager instance; private Properties properties; private ConfigManager() { loadConfig(); }
public static ConfigManager getInstance() { if (instance == null) { synchronized (ConfigManager.class) { if (instance == null) { instance = new ConfigManager(); } } } return instance; }
private void loadConfig() { properties = new Properties(); try { InputStream inputStream = getClass().getClassLoader() .getResourceAsStream("application.properties"); if (inputStream != null) { properties.load(inputStream); inputStream.close(); } } catch (IOException e) { System.err.println("加载配置文件失败: " + e.getMessage()); } }
public String getProperty(String key) { return properties.getProperty(key); }
public String getProperty(String key, String defaultValue) { return properties.getProperty(key, defaultValue); }
public void setProperty(String key, String value) { properties.setProperty(key, value); } }
|
3.2 数据库连接池单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
public class DatabaseConnectionPool { private static volatile DatabaseConnectionPool instance; private Queue<Connection> connectionPool; private int maxConnections; private String url; private String username; private String password; private DatabaseConnectionPool() { initializePool(); }
public static DatabaseConnectionPool getInstance() { if (instance == null) { synchronized (DatabaseConnectionPool.class) { if (instance == null) { instance = new DatabaseConnectionPool(); } } } return instance; }
private void initializePool() { ConfigManager config = ConfigManager.getInstance(); this.url = config.getProperty("db.url", "jdbc:mysql://localhost:3306/test"); this.username = config.getProperty("db.username", "root"); this.password = config.getProperty("db.password", "password"); this.maxConnections = Integer.parseInt(config.getProperty("db.max.connections", "10")); this.connectionPool = new ConcurrentLinkedQueue<>(); for (int i = 0; i < maxConnections; i++) { try { Connection connection = DriverManager.getConnection(url, username, password); connectionPool.offer(connection); } catch (SQLException e) { System.err.println("创建数据库连接失败: " + e.getMessage()); } } }
public synchronized Connection getConnection() { Connection connection = connectionPool.poll(); if (connection == null) { try { connection = DriverManager.getConnection(url, username, password); } catch (SQLException e) { System.err.println("创建新连接失败: " + e.getMessage()); } } return connection; }
public synchronized void returnConnection(Connection connection) { if (connection != null && !connection.isClosed()) { connectionPool.offer(connection); } }
public synchronized void closePool() { while (!connectionPool.isEmpty()) { Connection connection = connectionPool.poll(); try { if (connection != null && !connection.isClosed()) { connection.close(); } } catch (SQLException e) { System.err.println("关闭连接失败: " + e.getMessage()); } } } }
|
3.3 缓存管理器单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
public class CacheManager { private static volatile CacheManager instance; private Map<String, Object> cache; private Map<String, Long> cacheTimestamps; private long defaultExpirationTime; private CacheManager() { initializeCache(); }
public static CacheManager getInstance() { if (instance == null) { synchronized (CacheManager.class) { if (instance == null) { instance = new CacheManager(); } } } return instance; }
private void initializeCache() { this.cache = new ConcurrentHashMap<>(); this.cacheTimestamps = new ConcurrentHashMap<>(); ConfigManager config = ConfigManager.getInstance(); this.defaultExpirationTime = Long.parseLong( config.getProperty("cache.default.expiration", "3600000")); }
public void put(String key, Object value) { put(key, value, defaultExpirationTime); }
public void put(String key, Object value, long expirationTime) { cache.put(key, value); cacheTimestamps.put(key, System.currentTimeMillis() + expirationTime); }
public Object get(String key) { Long expirationTime = cacheTimestamps.get(key); if (expirationTime != null && System.currentTimeMillis() > expirationTime) { remove(key); return null; } return cache.get(key); }
public void remove(String key) { cache.remove(key); cacheTimestamps.remove(key); }
public void clear() { cache.clear(); cacheTimestamps.clear(); }
public int size() { return cache.size(); }
public void cleanupExpiredCache() { long currentTime = System.currentTimeMillis(); cacheTimestamps.entrySet().removeIf(entry -> { if (currentTime > entry.getValue()) { cache.remove(entry.getKey()); return true; } return false; }); } }
|
3.4 日志管理器单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
public class LogManager { private static volatile LogManager instance; private Logger logger; private String logLevel; private String logFile; private LogManager() { initializeLogger(); }
public static LogManager getInstance() { if (instance == null) { synchronized (LogManager.class) { if (instance == null) { instance = new LogManager(); } } } return instance; }
private void initializeLogger() { ConfigManager config = ConfigManager.getInstance(); this.logLevel = config.getProperty("log.level", "INFO"); this.logFile = config.getProperty("log.file", "application.log"); this.logger = Logger.getLogger(LogManager.class.getName()); Level level = Level.parse(logLevel); logger.setLevel(level); try { FileHandler fileHandler = new FileHandler(logFile, true); fileHandler.setFormatter(new SimpleFormatter()); logger.addHandler(fileHandler); } catch (IOException e) { System.err.println("创建日志文件处理器失败: " + e.getMessage()); } ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setFormatter(new SimpleFormatter()); logger.addHandler(consoleHandler); }
public void info(String message) { logger.info(message); }
public void warning(String message) { logger.warning(message); }
public void error(String message) { logger.severe(message); }
public void error(String message, Throwable throwable) { logger.log(Level.SEVERE, message, throwable); }
public void debug(String message) { logger.fine(message); } }
|
4. 单例模式性能优化
4.1 性能测试工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
public class SingletonPerformanceTest { private static final int THREAD_COUNT = 100; private static final int OPERATION_COUNT = 10000;
public static void testEagerSingleton() { long startTime = System.currentTimeMillis(); for (int i = 0; i < OPERATION_COUNT; i++) { EagerSingleton.getInstance().doSomething(); } long endTime = System.currentTimeMillis(); System.out.println("饿汉式单例性能测试完成,耗时: " + (endTime - startTime) + "ms"); }
public static void testLazySingleton() { long startTime = System.currentTimeMillis(); for (int i = 0; i < OPERATION_COUNT; i++) { LazySingleton.getInstance().doSomething(); } long endTime = System.currentTimeMillis(); System.out.println("懒汉式单例性能测试完成,耗时: " + (endTime - startTime) + "ms"); }
public static void testThreadSafeLazySingleton() { long startTime = System.currentTimeMillis(); for (int i = 0; i < OPERATION_COUNT; i++) { ThreadSafeLazySingleton.getInstance().doSomething(); } long endTime = System.currentTimeMillis(); System.out.println("线程安全懒汉式单例性能测试完成,耗时: " + (endTime - startTime) + "ms"); }
public static void testDoubleCheckedLockingSingleton() { long startTime = System.currentTimeMillis(); for (int i = 0; i < OPERATION_COUNT; i++) { DoubleCheckedLockingSingleton.getInstance().doSomething(); } long endTime = System.currentTimeMillis(); System.out.println("双重检查锁定单例性能测试完成,耗时: " + (endTime - startTime) + "ms"); }
public static void testStaticInnerClassSingleton() { long startTime = System.currentTimeMillis(); for (int i = 0; i < OPERATION_COUNT; i++) { StaticInnerClassSingleton.getInstance().doSomething(); } long endTime = System.currentTimeMillis(); System.out.println("静态内部类单例性能测试完成,耗时: " + (endTime - startTime) + "ms"); }
public static void testEnumSingleton() { long startTime = System.currentTimeMillis(); for (int i = 0; i < OPERATION_COUNT; i++) { EnumSingleton.getInstance().doSomething(); } long endTime = System.currentTimeMillis(); System.out.println("枚举单例性能测试完成,耗时: " + (endTime - startTime) + "ms"); }
public static void testMultiThreadPerformance() { ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT); CountDownLatch latch = new CountDownLatch(THREAD_COUNT); long startTime = System.currentTimeMillis(); for (int i = 0; i < THREAD_COUNT; i++) { executor.submit(() -> { try { for (int j = 0; j < OPERATION_COUNT / THREAD_COUNT; j++) { StaticInnerClassSingleton.getInstance().doSomething(); } } finally { latch.countDown(); } }); } try { latch.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } long endTime = System.currentTimeMillis(); System.out.println("多线程性能测试完成,耗时: " + (endTime - startTime) + "ms"); executor.shutdown(); }
public static void runAllTests() { System.out.println("开始单例模式性能测试..."); testEagerSingleton(); testLazySingleton(); testThreadSafeLazySingleton(); testDoubleCheckedLockingSingleton(); testStaticInnerClassSingleton(); testEnumSingleton(); testMultiThreadPerformance(); System.out.println("所有性能测试完成!"); } }
|
4.2 单例模式最佳实践
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
public class BestPracticeSingleton { private static class SingletonHolder { private static final BestPracticeSingleton INSTANCE = new BestPracticeSingleton(); } private BestPracticeSingleton() { if (SingletonHolder.INSTANCE != null) { throw new RuntimeException("不允许通过反射创建实例"); } }
public static BestPracticeSingleton getInstance() { return SingletonHolder.INSTANCE; }
private Object readResolve() { return getInstance(); }
public void doSomething() { System.out.println("BestPracticeSingleton正在处理业务逻辑"); } }
|
5. 实际应用示例
5.1 Spring Boot中的单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
@RestController @RequestMapping("/api") public class UserController { @Autowired private UserService userService; @Autowired private CacheManager cacheManager; @Autowired private LogManager logManager;
@GetMapping("/user/{userId}") public ResponseEntity<User> getUser(@PathVariable Long userId) { try { logManager.info("获取用户信息,用户ID: " + userId); String cacheKey = "user:" + userId; User user = (User) cacheManager.get(cacheKey); if (user == null) { user = userService.getUserById(userId); if (user != null) { cacheManager.put(cacheKey, user, 3600000); } } return ResponseEntity.ok(user); } catch (Exception e) { logManager.error("获取用户信息失败", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } }
@PostMapping("/user") public ResponseEntity<User> createUser(@RequestBody User user) { try { logManager.info("创建用户,用户名: " + user.getUsername()); User createdUser = userService.createUser(user); cacheManager.remove("user:" + createdUser.getId()); return ResponseEntity.ok(createdUser); } catch (Exception e) { logManager.error("创建用户失败", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } }
|
5.2 单例模式在微服务中的应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
@Component public class ServiceRegistry { private static volatile ServiceRegistry instance; private Map<String, ServiceInfo> services; private String registryUrl; private ServiceRegistry() { initializeRegistry(); }
public static ServiceRegistry getInstance() { if (instance == null) { synchronized (ServiceRegistry.class) { if (instance == null) { instance = new ServiceRegistry(); } } } return instance; }
private void initializeRegistry() { this.services = new ConcurrentHashMap<>(); ConfigManager config = ConfigManager.getInstance(); this.registryUrl = config.getProperty("registry.url", "http://localhost:8761"); }
public void registerService(String serviceName, ServiceInfo serviceInfo) { services.put(serviceName, serviceInfo); LogManager.getInstance().info("服务注册成功: " + serviceName); }
public void unregisterService(String serviceName) { services.remove(serviceName); LogManager.getInstance().info("服务注销成功: " + serviceName); }
public ServiceInfo getService(String serviceName) { return services.get(serviceName); }
public Map<String, ServiceInfo> getAllServices() { return new HashMap<>(services); }
public static class ServiceInfo { private String serviceName; private String host; private int port; private String status; private long lastHeartbeat; public ServiceInfo(String serviceName, String host, int port) { this.serviceName = serviceName; this.host = host; this.port = port; this.status = "UP"; this.lastHeartbeat = System.currentTimeMillis(); } public String getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.serviceName = serviceName; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public long getLastHeartbeat() { return lastHeartbeat; } public void setLastHeartbeat(long lastHeartbeat) { this.lastHeartbeat = lastHeartbeat; } } }
|
6. 总结
6.1 单例模式最佳实践
- 推荐使用静态内部类或枚举: 线程安全,性能好,代码简洁
- 避免使用懒汉式: 除非有特殊需求,否则不推荐使用
- 注意线程安全: 在多线程环境下确保实例唯一性
- 防止反射攻击: 在构造函数中添加检查
- 防止反序列化破坏: 实现readResolve方法
6.2 性能对比
- 饿汉式: 性能最好,但可能浪费资源
- 懒汉式: 性能较差,非线程安全
- 双重检查锁定: 性能较好,线程安全
- 静态内部类: 性能好,线程安全,推荐使用
- 枚举: 性能好,线程安全,推荐使用
6.3 使用场景
- 配置管理: 系统配置信息管理
- 连接池: 数据库连接池管理
- 缓存管理: 应用程序缓存管理
- 日志管理: 日志记录管理
- 服务注册: 微服务注册中心
通过本文的Java单例模式实战指南,您可以掌握单例模式的各种实现方式及其在实际项目中的应用。记住,选择合适的单例模式实现方式,确保线程安全和性能优化,是成功应用单例模式的关键。