单例模式总结

单例写法:

1:饿汉单例模式

优点:在类加载的时候就初始化,避免多线程造成产生多个实例的问题

缺点:不确定在是不是使用的情况就初始化,浪费空间,如果大量使用这个单例写法,浪费空间巨大

2:懒汉单例模式

2.1: 简单懒加载

优点:用户使用时才创建,避免内存浪费

缺点:在多线程情况下回产生多个实例

2.2:同步方法

优点:用户使用时才创建,在多线程场景依然可以保持一个实例

缺点:锁的粒度大,如果初始化实例时需要花费的时间长,容易导致死锁的情况

2.3:DoubleCheck

优点:用户使用时才创建,在多线程场景依然可以保持一个实例且锁的粒度降低,可以避免死锁情况

缺点:内部依然使用synchronized悲观锁,需要牺牲一部分性能

3:静态内部类单例模式

优点:巧妙运用JVM底层类加载顺序解决多个实例的问题,不依赖synchronize锁,性能好

缺点:无法避免反射和序列化的攻击

4:注册式单例模式

4.1:枚举

优点:不依赖synchronize锁,性能好,天然避免了反射攻击和序列化攻击

缺点:类加载就产生了实例,跟饿汉单例模式会浪费空间

4.2:容器

优点:通过容器的方式管理所有的单例对象

缺点:无法避免反射攻击

5:ThreadLocal单例

优点:类加载就初始化当前线程的实例对象,不需要synchronize锁就可以规避多线程问题

缺点:跟着类加载就创建,浪费空间,伪单例,只能满足当前的线程的单例,跨线程不满足

破坏单例

反射攻击:通过Class的api可以无视私有的构造器,绕过限制去创建实例

规避方法:在私有的构造器方法加入判断代码,如果当前有实例存在就抛出异常

序列化攻击:通过对象输出流蒋当前获取到的单例对象输出文件中,然后通过对象输入流构建新的对象

规避方法:在单例类中加resolve方法,返回值为当前对象实例即可

枚举单例模式获得了Class底层api和ObjectInputStream的read api的buffer加持,天然对反射和序列化攻击免疫

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 定义 确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。 使用场景 确保某个类有且只有一个的场景,避...
    烟火雨落阅读 2,405评论 0 0
  • 使用场景 要求生成唯一序列号的环境 在整个项目中需要一个共享访问点或共享数据例如一个Web页面上的计数器,可以不用...
    niaoge2016阅读 3,110评论 0 0
  • 单例模式 定义:确保某一个类只有一个实例,自行实例化并且想整个系统提供这个实例。 使用场景:避免某个类产生多个对象...
    luoyoub阅读 1,481评论 0 0
  • 之前在面试中,被面试官问到了设计模式,很自信的说了解单例模式。然后问我知道哪些实现方式,说出你觉得最好的是哪一种方...
    发霉的荷尔蒙2阅读 5,049评论 11 32
  • 今天没有加班,打算回到家好好复习英语,再阅读一小时,根据阅读计划,今天应该把《将心注入》这本书看完,在路上和...
    禾苗青青阅读 4,042评论 3 10

友情链接更多精彩内容