单例模式(Singleton mode)
一、概念
采取一定的方法保证在整个软件系统中 ,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
一、应用场景
- 只需要一个实例
- 各种 Manager
- 各种 Factory
三、设计模式写法(八种)
1.饿汉式 (静态常量)
class Singleton {
private Singleton() {}
private final static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
1. 构造器私有化
2. 类的内部创建对象
3. 向外暴露一个静态公共方法(getInstance)
4. 代码实现
2. 饿汉式(静态代码块)
class Singleton {
private Singleton() {}
private static Singleton instance;
static {
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}
小结:饿汉式说白了就是创建类的时候创建实例,这样可以保证线程安全,但是如果项目中没有用到就会造成资源浪费
3. 懒汉式(线程不安全)
class Singleton {
private Singleton() {}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
4. 懒汉式(线程安全,同步方法)
class Singleton {
private Singleton() {}
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
这种方式会效率太低,不推荐使用
5. 懒汉式(线程安全,同步代码块)
class Singleton {
private Singleton() {}
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
synchronized (this.class){
instance = new Singleton();
}
}
return instance;
}
}
不能起到线程同步的作用,在实际中不能使用
6.双重检查(Double Check)
class Singleton {
private Singleton() {}
private volatile static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
两次 if (instance == null)
解决线程安全问题,同时解决懒加载问题,推荐使用
7.静态内部类
class Singleton {
private Singleton() {}
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
这种方式 采用了类加载机制保证初始化实例时只有一个线程
避免了线程不安全,利用静态内部类特点实现延迟加载,效率高,推荐使用
8. 枚举
不仅能避免多线程同步问题,而且还能防止反序列话重新创建新的对象提倡使用
四、小结
- 单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
- 想实例化一个单例类的时候,使用相应的获取方法,而不是使用 new
- 单例模式使用的场景
- 需要
频繁进行创建和销毁的对象
(各种池) - 创建对象耗时过多或耗费资源过多,但是又经常用到的对象、工具类对象、频繁访问的数据库、文件的对象(数据源、session工厂等)
- 需要
在实际使用中,多使用饿汉式(两种方法)、双重检查、静态内部类、枚举