美文网首页
单例模式

单例模式

作者: Litchi_0424 | 来源:发表于2019-03-26 14:33 被阅读0次

    单例(Singleton)模式

    非延迟加载的模式就不介绍了

    说一下多线程下的延迟加载

    简单加锁

    就是在getInstance方法上面直接加上隐式锁

    public static synchronized SingletonExample getInstance(){
        if(null==instance){
            instance = new SingletonExample();    
        }
        return instance;
    }
    

    双重检查锁定

    先来看看错误的写法

    public static SingletonExample getInstance(){
        if(null===instance)
            synchronized(SingletonExample.class){
                if(null=instance){
                    instance = new SingletonExample();
                }
            }
        }
        return instnce;
    }
    

    这个写法表面看起来很没有问题,先检查一遍,要是是null,就进入锁代码,这是要是有别的线程在new这个实例,那么就会等待,在进入临界区后,再进行一次判断。但是这个写法最大的问题就是,在判断的时候,若判断存在这个instance,就直接返回,但是这个instance,可能是其他线程已经还未初始化完毕的instance,这样就产生错误。

    创建实例的操作有三个子操作

    objRef=allocate(SingletonExample.class)
    invokeConstructor(objRef);//初始化objRef的操作
    instance = objRef
    //在实际执行的时候,有可能重排序,导致先执行三,这个instance还没初始化完毕
    

    所以这里为了保证程序的有序性,我们就必须使用volatile来修饰instance变量。

    private static volatile SingletonExample instance;
    public static SingletonExample getInstance(){
        if(null===instance)
            synchronized(SingletonExample.class){
                if(null=instance){
                    instance = new SingletonExample();
                }
            }
        }
        return instnce;
    }
    

    静态内部类

    使用内部类来保存外部类的唯一实例,这样在调用这个外部类的静态方法的时候,并不会将这个实例给初始化,只有在访问内部类时候,才会将内部类的类变量初始化,而且每个类的类变量只会初始化一次。

    public class StaticSingletonExample{
        private static class InstanceHolder{
            final static StaticSingletonExample INSTANCE =new StaticSingletonExample();
        }
        public static StaticSingletonExample getInstance(){
            return InstanceHolder.INSTANCE;
        }
    }
    

    利用枚举类

    枚举类型相当于一个单例类,他的字段相当于该类的唯一实例。相比于普通饿汉模式,这个的优点主要是可以自由序列化,以及代码比较简单,他可以保证单例,线程安全(枚举类本质上是一个final类,其中的枚举实例是final static的,构造方法是私有的,在一个static域中进行枚举实例的初始化)。

    public static enum Singleton{
        INSTANCE;
        Singleton(){
            //私有构造器
        }
    }
    

    相关文章

      网友评论

          本文标题:单例模式

          本文链接:https://www.haomeiwen.com/subject/zjebvqtx.html