设计模式系列---两种懒汉式延迟加载单例模式

兴趣所致,上代码:

/**
 * 基于双重锁机制的延迟加载单例模式
 * 
 * @author Administrator
 *
 */
public class NotePadDoubleSingle {
    private static volatile NotePadDoubleSingle single = null;
    private NotePadDoubleSingle(){};
    public static NotePadDoubleSingle getInstance (){
        if(single == null){
            synchronized (NotePadDoubleSingle.class) {
                if(single == null){
                    single = new NotePadDoubleSingle();
                }
            }
        }
        return single;
    }
}
/**
 * 基于静态类加载的延迟加载单利模式
 * 
 * @author Administrator
 *
 */
class NotePadLoadSingle{
    private NotePadLoadSingle(){};
    private static class NotePadLoadSingleHolder{
        public static NotePadLoadSingle single = new NotePadLoadSingle();
    }
    public static NotePadLoadSingle getInstance(){
        return NotePadLoadSingleHolder.single;
    }
}

分析

  DCL(Double check lock)添加volatile 修饰的原因:

  首先分析,创建对象的过程,实例化对象一般分为三个过程。

    1、分配内存空间。

    2 、初始化对象。

    3 、将内存空间地址赋值给对象的引用。

  但是由于重排序的缘故,步骤2、3可能会发生重排序,其过程如下

    1、分配内存空间

    2、将内存空间的地址赋值给对应的引用

    3、初始化对象

    如果不加volatile的话,可能线程1在初始化的时候重排序了,线程2看到singleton != null,已经返回singleton,其实线程1还没有完成初始化,仅仅只不过是分配了内存空间而已!

原文地址:https://www.cnblogs.com/chihirotan/p/6561763.html