一、单例模式基本概念
单例模式(Singleton Pattern)是一种创建型设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点。单例模式常用于需要频繁访问且全局共享的对象,例如配置文件读取器、日志记录器、数据库连接池等。
二、单例模式的优势及缺点
优势:
- 节省资源:只创建一个实例,减少了内存开销。
- 全局访问:提供一个全局访问点,方便管理和访问。
- 控制实例数量:确保一个类只有一个实例,避免了实例冲突。
缺点:
- 不易扩展:由于单例类限制了实例数量,因此不容易进行扩展和修改。
- 隐藏依赖:全局访问点可能导致代码中隐含依赖,降低了代码的可维护性和测试性。
- 多线程问题:在多线程环境下,如果不正确实现单例模式,可能会导致线程安全问题。
三、单例模式的多种写法
1. 懒汉式(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2.双重检查锁定(推荐)
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;
}
}
3.静态内部类(推荐)
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
四、面试集合知识点汇总及解答
- 单例模式的应用场景:
- 配置文件读取器:配置文件通常只需要读取一次。
- 日志记录器:日志记录需要全局共享的单例对象。
- 数据库连接池:数据库连接池需要控制连接实例数量,且全局共享。
- 如何实现线程安全的单例模式:
- 使用双重检查锁定或者静态内部类实现。
- 单例模式中的反射攻击及解决方法:
- 反射可以破坏单例模式,可以在构造方法中使用
if (instance != null) throw new RuntimeException("Singleton instance already created!");
来防止。
- 反射可以破坏单例模式,可以在构造方法中使用
- 单例模式与Spring框架的结合:
- 在Spring中,可以通过定义Bean的scope为singleton来实现单例模式。