美文网首页
设计模式——单例模式

设计模式——单例模式

作者: Samuel_Tom | 来源:发表于2018-09-06 16:42 被阅读0次

    单例模式的定义

    单例模式保证一个类在全局中只有一个实例对象。

    单例模式的几种实现方式

    饿汉模式

    在类加载的时候就已经实例化对象,没有延迟加载,但由于类加载的机制能保证线程安全,典型的空间换时间;

    饿汉模式

    懒汉模式

    只有在调用getInstance()的时候才会实例化对象,但需要加上synchronized关键字保证线程安全,具有延迟加载的功能,
    典型的时间换空间,与饿汉相比会比较消耗性能。

    懒汉模式

    DCL双重检查模式

    懒汉模式的改进版,主要有两个地方的改进:同步锁改进和线程安全改进
    同步改进:采用了双重检查的模式,第一层检查避免了不必要的加锁同步;第二层检查保证实例为null时才会初始化实例对象;
    线程安全改进:实例变量采用了volatile关键字声明,volatile的语义能禁止指令重排序;在JVM中有一种优化机制叫乱序执行,也就是说为了执行效率,CPU可能不会按照代码的顺序执行,但是最终的执行结果跟代码顺序执行的结果是一致的。在这里volatile主要是解决DCL模式失效的问题,因为在new Singleton()初始化对象时不是一个原子操作,主要有三步:
    (1)为实例变量分配内存;
    (2)调用构造函数;
    (3)实例变量执行已经分配的内存地址;
    如果CPU乱序执行的话,有可能会按(1)(3)(2)的顺序执行,如果此时有线程A和线程B,线程A执行完了(3)还未执行(2)之前,切换到了线程B,那么此时线程B获得的实例就是非null的,线程B就直接返回该未初始化完成的实例对象,导致DCL失效。

    DCL双重检查模式

    静态内部类

    其实就是饿汉模式的改进版本,增加了延迟加载的功能。不会在类加载的时候就实例化对象,只有在调用getInstance()的时候才会实例化,同时由于内部类加载的方式可以保证线程安全,写起来也比较简单。

    静态内部类

    补充

    1、单例的构造函数必须声明为private,保证不会被外界通过new的方式进行实例化;

    相关文章

      网友评论

          本文标题:设计模式——单例模式

          本文链接:https://www.haomeiwen.com/subject/qmqnwftx.html