设计模式
单例模式
定义:一个类只有一个实例
构造方法私有,提供一个静态的成员变量,提供公共静态方法访问
分类
-
饿汉式:一开始就生成实例
-
懒汉式:需要时才生成实例
-
实现方式:
-
饿汉式
-
枚举饿汉式
-
懒汉式
-
双检锁懒汉式
-
静态内部类懒汉式
-
破坏单例:反射破坏单例、反序列化破坏单例(单例实现了序列化接口)、Unsafe破坏单例
-
反射破坏原理:获取单例的类名,用反射机制强行访问构造方法,生成新的对象。
-
防止反射破坏:在构造方法中判断是否已经生成实例,如有则抛出异常。
反序列化破坏:
-
防止:写一个特殊方法 readResolve
public Object readResolve(){ //返回本来已有的实例 return INSTANCE; }
-
枚举类单例可以防止反射破坏、反序列化破坏
-
懒汉式:
-
懒汉式多线程时会有问题
-
解决(双检锁):
- volatile:保证数据的可见性、有序性
- 如果没有volatile,指令会重排序,可能会返回构造未完全的实例。
-
懒汉式——静态内部类:
-
不用考虑线程安全问题
-
jdk中哪里使用了单例
- Runtime类(exit方法退出虚拟机、gc方法)
- System类中的Consolo(控制台)(双检锁懒汉式)
- Collections类(集合工具类)——Empt开头的类一般都是