![](https://img.haomeiwen.com/i6455343/7d26353600d8b32d.png)
![](https://img.haomeiwen.com/i6455343/606299f454b62226.png)
![](https://img.haomeiwen.com/i6455343/367434d48f5cb309.png)
![](https://img.haomeiwen.com/i6455343/84d1debf2814d665.png)
![](https://img.haomeiwen.com/i6455343/368c3d9e181a2816.png)
![](https://img.haomeiwen.com/i6455343/fd25661a88c1c54b.png)
![](https://img.haomeiwen.com/i6455343/aab517c7d040580d.png)
![](https://img.haomeiwen.com/i6455343/0dfdb183ad2c5af0.png)
单例模式
懒汉式
![](https://img.haomeiwen.com/i6455343/bdc3d5e28017ae11.png)
懒汉式改进1---synchronized
![](https://img.haomeiwen.com/i6455343/5c96a71060584d55.png)
加synchronized 在 11行代码上,注意synchronized加在static上锁的是LazySingleton这个类的class文件,而如果加的这个方法不是静态的,那么锁的是在堆内存中生成的对象
即加在static上的synchronized等价于如下:
![](https://img.haomeiwen.com/i6455343/040deba2262cbcbe.png)
因为加入了synchronized这种大范围的锁,所以在性能上有一定的消耗
懒汉式改进2---双重校验锁
![](https://img.haomeiwen.com/i6455343/adfabf7ab8bcc35c.png)
![](https://img.haomeiwen.com/i6455343/36cb72a4d9bbd936.png)
![](https://img.haomeiwen.com/i6455343/57983e112ea90a90.png)
两种方式解决重排序: 1.加volatile关键字 2.不允许其他线程看到当前线程的重排序
单例模式---静态内部类
![](https://img.haomeiwen.com/i6455343/12c28e2cce982304.png)
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;
}
防止反射攻击,在构造器加上判断,以上面的饿汉式为例:
![](https://img.haomeiwen.com/i6455343/722f7a6815cc0c0b.png)
未完----
网友评论