首先DCL是双重检查锁,懒汉式的一种实现方式
DCL方式可以实现单例,但可能发生线程获取到的对象未被初始化的场景
对象初始化过程
当使用new关键字创建一个对象时
JVM会为对象优先分配栈内存
内存分配完后设置默认属性值
执行构造函数,属性设置初始值
建立连接,引用指向对象内存地址
如果在对象未初始化的时候就先建立连接,使用DCL实现的单例模式就会导致线程拿到未被初始化的对象,未被初始化的对象属性为引用类型则值全部为null,一旦对这些属性进行操作则会抛出空指针异常
volatile关键字语意
多线程之间的可见性,当线程对其进行读写操作时JVM会强制要求去主线程读写,以保证其他线程读取的值是最新的
禁止指令重新排序,为保证建立连接前对象一定被初始化过了,不存在读取到的是一个没有初始化的一个半初始化状态的对象
DCL实现单例模式是需要加volatile关键字修饰单例的,否则可能导致线程读取到的是一个没被初始化的对象,从而导致程序出现不可预知的错误