代码如下(示例):
public class SingletonLazy { //创建当前类的引用 private static volatile SingletonLazy s; //声明当前类型的引用 private static SingletonLazy instance = null; //构造方法私有化 private SingletonLazy() { } // // 存在问题的获取实例方法代码 // //公共的获取当前对象的方法 // public static SingletonLazy getInstance() { // if (instance == null) { // instance = new SingletonLazy(); // } // // return instance; // } //代码d分为三个机器指令步骤 //步骤1:为new出来的对象开辟内存空间 //步骤2:初始化,执行构造器方法的逻辑代码片段 //步骤3:完成SingletonLazy引用的赋值操作,将其指向刚刚开辟的内存地址 //对外提供公共的访问方法将SingletonHungary对象暴露给外部 public static SingletonLazy getInstance() { if(s == null){// a //这里有可能会有两个线程进来,所以还需要在下面再次判断s是否为null,该方式被称为双重检查 //问题场景:线程1执行到d,线程2执行到a,此时d指令重排为132,s非空,但是没执行构造方法,是不完整的 synchronized(SingletonLazy.class) {// b if(s == null){// c s = new SingletonLazy();// d } } } return s; } }