单例模式-LazyDoubleCheckSingleton(懒加载双重检查锁)
public class LazyDoubleCheckSingleton { private static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null; private LazyDoubleCheckSingleton(){ } public static LazyDoubleCheckSingleton getInstance(){ if(lazyDoubleCheckSingleton == null){ synchronized (LazyDoubleCheckSingleton.class){ if(lazyDoubleCheckSingleton == null){ lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton(); //1.分配内存给这个对象 // //3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址 //2.初始化对象 // intra-thread semantics // ---------------//3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址 } } } return lazyDoubleCheckSingleton; } }
以上的双重检查锁代码的缺点:
1.会发生指定重排序
//1.分配内存给这个对象
//2.初始化对象
//3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址
假设一种情况:
两个线程同时访问对象,如果编译器优化之后,一个线程执行顺序为1.3.2,当线程1执行到3的时候,那么线程2执行生成对象的时候就会没有对象.
解决办法关键字:Volatile
1.保证共享内存的可见性。
2.禁止指令重排序。