一、定义
二、使用场景
三、优缺点
1、优点
2、缺点
四、代码实现
1、懒汉式
- 在被客户端首次调用的时候才会创建唯一实例
- 加入双重检查锁机制的懒汉模式能够确保线程安全
public class LazyDoubleCheckSingleton {
private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null;
private LazyDoubleCheckSingleton(){
}
public static LazyDoubleCheckSingleton getInstance(){
if(lazyDoubleCheckSingleton == null){
synchronized (LazyDoubleCheckSingleton.class){
if(lazyDoubleCheckSingleton == null){
lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
//1.分配内存给这个对象
// //3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址
//2.初始化对象
// intra-thread semantics
// ---------------//3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址
}
}
}
return lazyDoubleCheckSingleton;
}
}
2、饿汉式
类被加载的时候就立即初始化并创建唯一实例
public class HungrySingleton {
private final static HungrySingleton hungrySingleton;
static{
hungrySingleton = new HungrySingleton();
}
private HungrySingleton(){
if(hungrySingleton != null){
throw new RuntimeException("单例构造器禁止反射调用");
}
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
3、枚举饿汉式
public class EnumStarvingSingleton {
private EnumStarvingSingleton(){}
private EnumStarvingSingleton getInstance() {
return ContainerHolder.HOLDER.instance;
}
private enum ContainerHolder {
HOLDER;
private EnumStarvingSingleton instance;
ContainerHolder() {
instance = new EnumStarvingSingleton();
}
}
}
问题:枚举如何抵挡序列化和反序列化攻击?
线索:ObjectInputStream的readObject源码
4、源码地址
五、单例的破坏
1、序列化/反序列化
2、克隆
3、反射
4、枚举单例
5、容器单例
6、ThreadLocal单例
- threadLocal维护的对象是线程唯一的
- 是“容器单例”的一种实现