一、职责型模式
1.单例模式
懒汉式单例:有两个很重要的细节。
a.两重if的双重检查:
第一个if判断的作用:是为了提高程序的 效率,当Singleton对象被创建以后,再获取Singleton对象时就不用去验证同步代码块的锁及后面的代码,直接返回Singleton对象。
第二个if判断的作用:是为了解决多线程下的安全性问题,也就是保证对象的唯一。
b.使用volatile关键字来防止指令重排序。
instance = new Singleton();这条语句不是一个原子操作,编译后会多条字节码指令:
步骤1.为new出来的对象开辟内存空间。
步骤2.初始化,执行构造器方法的逻辑代码片段。
步骤3.完成instance引用的赋值操作,将其指向刚刚开辟的内存地址。
问题场景:
一个线程执行到instance = new Singleton();这条语句时,不是按照1,2,3来初始化一个对象,而是按照1,3,2的顺序,这样当这个线程执行完步骤3时,又有另外一个线程执行到第一层if判,它会判断instance不为空,而直接返回instance,此时instance是不一个不为null的但是没有初始化完成的对象。由于指令重排序导致第二个线程提前拿到了一个不完整的instance对象。

饿汉式单例:全局的单例实例在类装载时构建的实现方式,不存在线程安全问题。

网友评论