一、总结每种单例写法的优、缺点java
单例类型安全 |
优势多线程 |
缺点性能 |
饿汉式单例spa |
能够快速建立实例线程 |
在未使用时就初始化实例,占用内存空间3d |
懒汉式单例对象 |
只有在使用的时候,才会建立blog |
须要考虑多线程的安全问题,须要进行双重校验保证明例只被建立一次。可是添加锁后,会有性能问题内存 |
内部类方式单例 |
不须要考虑线程安全,没有性能问题 |
可经过反射和反序列化方式暴力破坏单例 |
枚举类方式单例(注册式单例) |
既能知足单例要求,又没法被反射和序列化方式破解 |
相对目前最优实现单例方式 |
容器注入方式单例(注册式单例) |
做为容器,可存放多种对象的单个实例 |
须要考虑多线程安全问题,添加锁 |
二、思考破坏单例模式的方式有哪些?而且概括总结
目前破坏单例模式的方式主要有反射和序列化。
反射:普通java类能够经过反射获取到构造方法,从而调用构造方法建立新对象。
可是枚举类方式单例不能经过发射破坏,由于枚举单例反编译后能够看到,枚举类实际内部没有无参构造方法。另外,若是反射想经过调用有参构造方法,去建立实例时,反射机制的调用源码已经作了判断,判断当前调用类是不是枚举,若是是枚举类,则不容许进行反射调用构造方法建立实例对象。
序列化:序列化方式,当读取文件流生成对象时,若是是object类型,会去检查是否含有构造方法,若是有,会从新newInstance建立新对象。若是是枚举类型,会没有调用new 对象的动做,而是根据枚举名称直接获取枚举值。因此枚举类方式单例不会被反序列化破解,普通单例能够。
三、梳理内部类的执行逻辑,并画出时序图。