1. 单例模式概述

单例模式(Singleton Pattern)是设计模式中最简单也是最常用的模式之一。它确保一个类只有一个实例,并提供一个全局访问点。在Java应用中,单例模式常用于处理所有请求,如配置管理、连接池、缓存管理等场景。本文将详细介绍单例模式的各种实现方式及其在Java实战中的应用。

1.1 核心特点

  1. 唯一实例: 确保类只有一个实例
  2. 全局访问: 提供全局访问点
  3. 线程安全: 在多线程环境下保证实例唯一性
  4. 延迟加载: 支持懒加载和饿汉式加载
  5. 性能优化: 减少对象创建开销

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
/**
* 饿汉式单例模式
* 特点:类加载时就创建实例,线程安全,但可能造成资源浪费
* @author 运维实战
*/
public class EagerSingleton {

// 私有静态实例,类加载时就创建
private static final EagerSingleton INSTANCE = new EagerSingleton();

// 私有构造函数,防止外部实例化
private EagerSingleton() {
System.out.println("EagerSingleton实例被创建");
}

/**
* 获取单例实例
* @return 单例实例
*/
public static EagerSingleton getInstance() {
return INSTANCE;
}

/**
* 业务方法示例
*/
public void doSomething() {
System.out.println("EagerSingleton正在处理业务逻辑");
}

/**
* 防止反序列化破坏单例
* @return 单例实例
*/
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
/**
* 懒汉式单例模式(非线程安全)
* 特点:延迟加载,但非线程安全
* @author 运维实战
*/
public class LazySingleton {

// 私有静态实例
private static LazySingleton instance;

// 私有构造函数
private LazySingleton() {
System.out.println("LazySingleton实例被创建");
}

/**
* 获取单例实例(非线程安全)
* @return 单例实例
*/
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
/**
* 懒汉式单例模式(线程安全)
* 特点:延迟加载,线程安全,但性能较差
* @author 运维实战
*/
public class ThreadSafeLazySingleton {

// 私有静态实例
private static ThreadSafeLazySingleton instance;

// 私有构造函数
private ThreadSafeLazySingleton() {
System.out.println("ThreadSafeLazySingleton实例被创建");
}

/**
* 获取单例实例(线程安全)
* 使用synchronized关键字保证线程安全
* @return 单例实例
*/
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
/**
* 双重检查锁定单例模式
* 特点:延迟加载,线程安全,性能较好
* @author 运维实战
*/
public class DoubleCheckedLockingSingleton {

// 使用volatile关键字保证可见性
private static volatile DoubleCheckedLockingSingleton instance;

// 私有构造函数
private DoubleCheckedLockingSingleton() {
System.out.println("DoubleCheckedLockingSingleton实例被创建");
}

/**
* 获取单例实例(双重检查锁定)
* @return 单例实例
*/
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
/**
* 静态内部类单例模式
* 特点:延迟加载,线程安全,性能好,推荐使用
* @author 运维实战
*/
public class StaticInnerClassSingleton {

// 私有构造函数
private StaticInnerClassSingleton() {
System.out.println("StaticInnerClassSingleton实例被创建");
}

/**
* 静态内部类
* 只有在调用getInstance()时才会加载内部类,实现延迟加载
*/
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}

/**
* 获取单例实例
* @return 单例实例
*/
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
/**
* 枚举单例模式
* 特点:线程安全,防止反序列化破坏单例,推荐使用
* @author 运维实战
*/
public enum EnumSingleton {

// 枚举实例
INSTANCE;

/**
* 业务方法示例
*/
public void doSomething() {
System.out.println("EnumSingleton正在处理业务逻辑");
}

/**
* 获取单例实例
* @return 单例实例
*/
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
/**
* 配置管理器单例
* 用于管理应用程序配置信息
* @author 运维实战
*/
public class ConfigManager {

private static volatile ConfigManager instance;
private Properties properties;

// 私有构造函数
private ConfigManager() {
loadConfig();
}

/**
* 获取单例实例
* @return 配置管理器实例
*/
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 {
// 从classpath加载配置文件
InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream("application.properties");
if (inputStream != null) {
properties.load(inputStream);
inputStream.close();
}
} catch (IOException e) {
System.err.println("加载配置文件失败: " + e.getMessage());
}
}

/**
* 获取配置值
* @param key 配置键
* @return 配置值
*/
public String getProperty(String key) {
return properties.getProperty(key);
}

/**
* 获取配置值(带默认值)
* @param key 配置键
* @param defaultValue 默认值
* @return 配置值
*/
public String getProperty(String key, String defaultValue) {
return properties.getProperty(key, defaultValue);
}

/**
* 设置配置值
* @param key 配置键
* @param value 配置值
*/
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
/**
* 数据库连接池单例
* 用于管理数据库连接
* @author 运维实战
*/
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();
}

/**
* 获取单例实例
* @return 数据库连接池实例
*/
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());
}
}
}

/**
* 获取数据库连接
* @return 数据库连接
*/
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;
}

/**
* 归还数据库连接
* @param 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
/**
* 缓存管理器单例
* 用于管理应用程序缓存
* @author 运维实战
*/
public class CacheManager {

private static volatile CacheManager instance;
private Map<String, Object> cache;
private Map<String, Long> cacheTimestamps;
private long defaultExpirationTime;

// 私有构造函数
private CacheManager() {
initializeCache();
}

/**
* 获取单例实例
* @return 缓存管理器实例
*/
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")); // 默认1小时
}

/**
* 存储缓存数据
* @param key 缓存键
* @param value 缓存值
*/
public void put(String key, Object value) {
put(key, value, defaultExpirationTime);
}

/**
* 存储缓存数据(带过期时间)
* @param key 缓存键
* @param value 缓存值
* @param expirationTime 过期时间(毫秒)
*/
public void put(String key, Object value, long expirationTime) {
cache.put(key, value);
cacheTimestamps.put(key, System.currentTimeMillis() + expirationTime);
}

/**
* 获取缓存数据
* @param key 缓存键
* @return 缓存值
*/
public Object get(String key) {
// 检查是否过期
Long expirationTime = cacheTimestamps.get(key);
if (expirationTime != null && System.currentTimeMillis() > expirationTime) {
remove(key);
return null;
}

return cache.get(key);
}

/**
* 删除缓存数据
* @param key 缓存键
*/
public void remove(String key) {
cache.remove(key);
cacheTimestamps.remove(key);
}

/**
* 清空所有缓存
*/
public void clear() {
cache.clear();
cacheTimestamps.clear();
}

/**
* 获取缓存大小
* @return 缓存大小
*/
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
/**
* 日志管理器单例
* 用于管理应用程序日志
* @author 运维实战
*/
public class LogManager {

private static volatile LogManager instance;
private Logger logger;
private String logLevel;
private String logFile;

// 私有构造函数
private LogManager() {
initializeLogger();
}

/**
* 获取单例实例
* @return 日志管理器实例
*/
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);
}

/**
* 记录信息日志
* @param message 日志消息
*/
public void info(String message) {
logger.info(message);
}

/**
* 记录警告日志
* @param message 日志消息
*/
public void warning(String message) {
logger.warning(message);
}

/**
* 记录错误日志
* @param message 日志消息
*/
public void error(String message) {
logger.severe(message);
}

/**
* 记录错误日志(带异常)
* @param message 日志消息
* @param throwable 异常
*/
public void error(String message, Throwable throwable) {
logger.log(Level.SEVERE, message, throwable);
}

/**
* 记录调试日志
* @param message 日志消息
*/
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
/**
* 单例模式性能测试工具
* @author 运维实战
*/
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
/**
* 单例模式最佳实践示例
* @author 运维实战
*/
public class BestPracticeSingleton {

// 使用静态内部类实现单例
private static class SingletonHolder {
private static final BestPracticeSingleton INSTANCE = new BestPracticeSingleton();
}

// 私有构造函数
private BestPracticeSingleton() {
// 防止反射攻击
if (SingletonHolder.INSTANCE != null) {
throw new RuntimeException("不允许通过反射创建实例");
}
}

/**
* 获取单例实例
* @return 单例实例
*/
public static BestPracticeSingleton getInstance() {
return SingletonHolder.INSTANCE;
}

/**
* 防止反序列化破坏单例
* @return 单例实例
*/
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
/**
* Spring Boot中的单例模式应用
* @author 运维实战
*/
@RestController
@RequestMapping("/api")
public class UserController {

// 注入单例服务
@Autowired
private UserService userService;

@Autowired
private CacheManager cacheManager;

@Autowired
private LogManager logManager;

/**
* 获取用户信息
* @param userId 用户ID
* @return 用户信息
*/
@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); // 1小时过期
}
}

return ResponseEntity.ok(user);
} catch (Exception e) {
logManager.error("获取用户信息失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

/**
* 创建用户
* @param user 用户信息
* @return 创建结果
*/
@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
/**
* 微服务中的单例模式应用
* @author 运维实战
*/
@Component
public class ServiceRegistry {

private static volatile ServiceRegistry instance;
private Map<String, ServiceInfo> services;
private String registryUrl;

// 私有构造函数
private ServiceRegistry() {
initializeRegistry();
}

/**
* 获取单例实例
* @return 服务注册中心实例
*/
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<>();

// 从配置管理器获取注册中心URL
ConfigManager config = ConfigManager.getInstance();
this.registryUrl = config.getProperty("registry.url", "http://localhost:8761");
}

/**
* 注册服务
* @param serviceName 服务名称
* @param serviceInfo 服务信息
*/
public void registerService(String serviceName, ServiceInfo serviceInfo) {
services.put(serviceName, serviceInfo);
LogManager.getInstance().info("服务注册成功: " + serviceName);
}

/**
* 注销服务
* @param serviceName 服务名称
*/
public void unregisterService(String serviceName) {
services.remove(serviceName);
LogManager.getInstance().info("服务注销成功: " + serviceName);
}

/**
* 获取服务信息
* @param serviceName 服务名称
* @return 服务信息
*/
public ServiceInfo getService(String serviceName) {
return services.get(serviceName);
}

/**
* 获取所有服务
* @return 所有服务信息
*/
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;

// 构造函数、getter和setter方法
public ServiceInfo(String serviceName, String host, int port) {
this.serviceName = serviceName;
this.host = host;
this.port = port;
this.status = "UP";
this.lastHeartbeat = System.currentTimeMillis();
}

// getter和setter方法
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 单例模式最佳实践

  1. 推荐使用静态内部类或枚举: 线程安全,性能好,代码简洁
  2. 避免使用懒汉式: 除非有特殊需求,否则不推荐使用
  3. 注意线程安全: 在多线程环境下确保实例唯一性
  4. 防止反射攻击: 在构造函数中添加检查
  5. 防止反序列化破坏: 实现readResolve方法

6.2 性能对比

  • 饿汉式: 性能最好,但可能浪费资源
  • 懒汉式: 性能较差,非线程安全
  • 双重检查锁定: 性能较好,线程安全
  • 静态内部类: 性能好,线程安全,推荐使用
  • 枚举: 性能好,线程安全,推荐使用

6.3 使用场景

  • 配置管理: 系统配置信息管理
  • 连接池: 数据库连接池管理
  • 缓存管理: 应用程序缓存管理
  • 日志管理: 日志记录管理
  • 服务注册: 微服务注册中心

通过本文的Java单例模式实战指南,您可以掌握单例模式的各种实现方式及其在实际项目中的应用。记住,选择合适的单例模式实现方式,确保线程安全和性能优化,是成功应用单例模式的关键。