## 设计模式之单例懒汉式之双重检查volatile关键字版
package cn.qqjx.design;
/**
* lazy loading
* 也称懒汉式
* 虽然达到了按需初始化的目的,但却带来线程不安全的问题
* 可以通过synchronized解决,但也带来效率下降
*----------------------------------------------------------------
* 在双重验证中是否需要加 volatile 关键字?
* 答案: 需要加
* new 对象的三个过程
* 1 申请内存空间 给成员变量赋默认值
* 2 给成员变量赋初始值
* 3 栈的变量指向堆内存的地址
* 但是有指令重排序的风险 当成员变量还没有赋值的时候 栈的变量已经指向了对象
* ----------------------------------------------------------------
* 在这个单例中 第一个线程发生new 实例的时候 如果只是默认值 而没有完全初始化的情况下 在超高并发情况下 第二个线程
* 拿到的是半初始化的值
* 加了 volatile之后new对象的指令重排序就不复存在了
* volatile 禁止指令重排序
*/
public class Mgr06 {
private static /*volatile*/ Mgr06 INSTANCE; //JIT
private Mgr06() {
}
public static Mgr06 getInstance() {
if (INSTANCE == null) {
//双重检查
synchronized (Mgr06.class) {
if(INSTANCE == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Mgr06();
}
}
}
return INSTANCE;
}
public void m() {
System.out.println("m");
}
public static void main(String[] args) {
for(int i=0; i<10; i++) {
new Thread(()->{
System.out.println(Mgr06.getInstance().hashCode());
}).start();
}
}
}
103512977
103512977
103512977
103512977
103512977
103512977
103512977
103512977
103512977
103512977