zoukankan      html  css  js  c++  java
  • 设计模式-单例模式

    • 前言: 设计模式是一个经常被提及的话题,无论是日常开发还是面试,都会经常被提及。让举出一些常用的设计模式,基本都会首先列举: 单例模式 工厂模式。我们这个设计模式系列,也不去追求新颖,我们也从提及率最高的单例模式开始。
    •  使用场景:顾名思义,单例就是单实例的意思,是指在整个系统中,某个类的对象都只存在一个,同时对外有一个统一的暴露方法来获取这个实例。
    •  思路要点: 既然只能有一个对象存在,那就不能让人随便new,所以构造函数必须私有。同时要提供一个静态的public方法来获取这个实例。记住这两个要点,写出来其实就不太难
    • 单例模式的写法 通常有三种 : 饿汉模式  懒汉模式  以及最优秀的枚举模式。下面分别介绍这三种写法

     

    --  饿汉模式  (对象必须一直存在,不要等到我要使用的时候才给我创造,我很饿,等不及!)

     

    -- 懒汉模式(我不需要你一直存在,但是当我需要你时,你得存在)

     

    懒汉模式相比饿汉模式存在线程安全的问题,因为当多个线程同时访问 getInstance方法的时候,第一个线程 获取为null ,然后创建,同时第二个线程也正在访问,也创建了一个对象,那就和我们的初衷相违背了。所以我们在懒汉模式下,加上了 synchronized同步块来保证线程安全。这是要注意的一个点。

     

    这么说,上面两种方法就应该是不错的单例模式写法了,但是实际上在面对 序列化反序列化攻击的时候, 就会出现问题。

     

    测试这个方法,我们会发现 第一次 返回的是true,  而第二次通过序列化,反序列化折腾之后,就为false了。 饿汉模式同样存在这样的被攻击弊端。

    完美的解决方案就是 枚举模式实现的 单例

     

    是的,就是如此简单粗暴。。为什么枚举可以呢,因为枚举字节码反编译之后,Instance 也是以public static 的形式存在,同时枚举对象的 序列化只是将名字输出到结果中,而反序列化的时候,则是根据名字 查找枚举对象,因此,反序列化后的实例和被序列化的对象实例相同。

     

    测试之后,发现两次都是true ,完美!

       代码地址:  https://github.com/felixmaomao/design-patterns

  • 相关阅读:
    Ubuntu 20.04 国内下载eclipse 网速慢解决方案
    Ubuntu20.04+GeForce RTX 2080 SUPER+cuda11.1+cudnn8.0.4+openCV4.4.0编译
    计算机专业考研复试面试----计算机组成原理
    计算机专业考研复试面试----操作系统
    Gabor滤波(个人学习)
    局部保留投影算法(个人学习)
    【转载】matlab常用函数
    latex常见的错误(自己经常出现的)
    latex常用的宏包(转载)
    C语言基础知识
  • 原文地址:https://www.cnblogs.com/JasonShenW/p/8489740.html
Copyright © 2011-2022 走看看