1.单例模式
-
定义说明
创建型设计模式
确保某个类只有一个实例 -
适用场景
系统内只需要一个全局对象,减少对象创建带来的资源消耗
2.UML类图
-
角色介绍
Singleton: 单例类
Client: 客户类(适用者) -
要点
私有构造方法
公有静态方法返回实例对象
3.几种单例模式比较
常见4种单例模式:饿汉、懒汉、双重检查锁DCL、静态内部类方式
- 饿汉
public class SingletonEHan {
private static final SingletonEHan sInstance = new SingletonEHan();
private SingletonEHan() {
}
public static SingletonEHan getInstance() {
return sInstance;
}
}
- 懒汉
public class SingletonLanHan {
private static SingletonLanHan sInstance;
private SingletonLanHan() {
}
public static synchronized SingletonLanHan getInstance() {
if (sInstance == null) {
sInstance = new SingletonLanHan();
}
return sInstance;
}
}
- DCL
public class SingletonDCL {
private static SingletonDCL sInstance;
private SingletonDCL() {
}
public static SingletonDCL getInstance() {
if (sInstance == null) {
synchronized (SingletonDCL.class) {
if (sInstance == null) {
sInstance = new SingletonDCL();
}
}
}
return sInstance;
}
}
- 静态内部类方式
public class SingletonStaticInnerClass {
private SingletonStaticInnerClass() {
}
public static SingletonStaticInnerClass getInstance() {
return SingletonStaticInnerClassHolder.sInstance;
}
private static final class SingletonStaticInnerClassHolder {
private static final SingletonStaticInnerClass sInstance = new SingletonStaticInnerClass();
}
}
分类 | 说明 |
---|---|
饿汉 | 声明时就进行初始化,一般建议在使用时才初始化,不推荐使用 |
懒汉 | getInstance方法为同步方法,每次调用都会进行同步,会造成不必要的开销,不建议使用 |
DCL | 使用时初始化,第一层判空避免不必要的同步;第二层判空是为了在null的情况下创建实例,推荐适用 |
静态内部类 | 使用时初始化,第一次调用getInstance会导致JVM家长内部类,这种方式保证线程安全,也保证单例对象的唯一性,推荐使用 |
5.总结
- 单例模式优缺点
优点:减少内存开销、使用方便
缺点:扩展困难、适用不当引起内存泄漏 - 创建对象需要做3件事情
a. 给对象的实例分配内存;
b. 调用构造方法,成员变量初始化;
c. 将对象指向分配的内存空间,即对象不再为null。 - volatile会有一定的性能影响