什么是单例模式?
单例模式(Singleton Pattern)是最简单的设计模式之一,它保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式属于创建型模式。
为什么使用单例模式?
- 确保某个类只有一个实例
- 提供对该实例的全局访问点
- 控制共享资源的访问
单例模式的实现方式
1. 懒汉式(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}这种方式是最基本的实现方式,但它不是线程安全的。
2. 懒汉式(线程安全)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}通过synchronized关键字实现线程安全,但效率较低。
3. 双重检查锁定(DCL)
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}这种方式既保证了线程安全,又提高了效率。
4. 饿汉式
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}这种方式是线程安全的,但会在类加载时就初始化实例。
5. 静态内部类
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}这是推荐的实现方式,既保证了线程安全,又实现了懒加载。
使用场景
- 配置管理器
- 数据库连接池
- 线程池
- 日志管理器
- 缓存管理器
注意事项
- 构造函数必须是私有的
- 考虑线程安全问题
- 注意序列化和反序列化问题
- 防止反射攻击
总结
单例模式虽然简单,但实现时需要考虑多种因素。在实际开发中,建议使用静态内部类或枚举方式来实现单例模式,它们能够保证线程安全,并且实现简单。
代码示例:实际应用中的单例模式
// 配置管理器示例
public class ConfigManager {
private static volatile ConfigManager instance;
private Properties properties;
private ConfigManager() {
properties = new Properties();
try {
properties.load(new FileInputStream("config.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static ConfigManager getInstance() {
if (instance == null) {
synchronized (ConfigManager.class) {
if (instance == null) {
instance = new ConfigManager();
}
}
}
return instance;
}
public String getProperty(String key) {
return properties.getProperty(key);
}
}参考资料
- 《设计模式:可复用面向对象软件的基础》
- 《Effective Java》第三版
- Java API 文档

