设计模式笔记3--单例模式
单例模式
懒汉式
懒汉式改进1---synchronized
加synchronized 在 11行代码上,注意synchronized加在static上锁的是LazySingleton这个类的class文件,而如果加的这个方法不是静态的,那么锁的是在堆内存中生成的对象
即加在static上的synchronized等价于如下:
因为加入了synchronized这种大范围的锁,所以在性能上有一定的消耗
懒汉式改进2---双重校验锁
两种方式解决重排序: 1.加volatile关键字 2.不允许其他线程看到当前线程的重排序
单例模式---静态内部类
public class StaticInnerClassSingleton{
private static class InnerClass {
private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return InnerClass.staticInnerClassSingleton;
}
}
//必须私有构造器
private StaticInnerClassSingleton(){
}
原理,JVM在初始化一个类时,会对多个线程同步一个类的锁---即class对象的初始化锁,假设这时线程0获取到了这个锁,那么线程1是无法看到线程0在初始化这个类对象的内部操作(重排序)
饿汉式
在类加载的时候就完成了初始化,避免线程同步问题,缺点,没有延迟加载效果
public class HungrySingleton() {
private final static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance() {
return hungrySingleton;
}
}
单例的破坏和解决
如果单例模式中存在序列化和反序列化 那么单例模式会被破坏
即 用单例模式序列化到文件里,再反序列化文件出来的对象 和原先的对象不是同一个对象
解决方案: 在单例模式加上下面方法(以上面的饿汉式为例):
private Object readResolve(){
return hungrySingleton;
}
防止反射攻击,在构造器加上判断,以上面的饿汉式为例:
未完----