阅读 103

设计模式之单例模式

前言:因为博主本人实在是菜鸡本鸡,但是又想有自己的学习记录,所以才萌生了写博客的念头,虽然网上已经有大量前辈总结的好文了,我的作本相比前辈们的犹如星星之火相比太阳,但是总要有个慢慢记录的过程嘛,相信慢慢下去我也会有提高的。虽然我不敢保证我会是写的最好的,说这话也显得太狂了hh,但是我保证一定不抄袭,有引用会注明来源,保证自己所写的内容尽可能在一定时间内完全正确,毕竟技术日新月异,我想保证永远正确也不太现实。(本博客参考菜鸟教程写作)

单例模式概述:

单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)。(百度百科)

通俗来讲就是项目中无论怎样都是只有一个单例对象实例。

为什么要有单例模式?

按博主的理解是为了解决频繁创建销毁对象引起大量资源开销的场景,而且有的对象项目中确实只需要一个,比如数据库连接实例等等。

优点:

1.在内存中只有一个实例,节省资源开销;

2.避免对资源的多重占用(例如写文件操作)。

缺点:

没有接口,不能继承,与单一职责原则冲突,不适用于所需对象有变化的场景。

几种常见实现方式:

1.饿汉式(线程安全、非懒加载、实现简单)

class SingleInstance{    
    static SingleInstance singleInstance=new SingleInstance();    
    private SingleInstance(){        
        //构造方法私有化     
     }    
    public static SingleInstance getInstance(){        
        return singleInstance;    
    }
}
复制代码

2.非线程安全的懒汉式

class SingleInstance{
    SingleInstance singleInstance=null;
    private SingleInstance(){
        //构造方法私有化
    }

    public SingleInstance getSingleInstance() {
        return singleInstance;
    }
}
复制代码

3.线程安全的懒汉式(粗暴加上synchronized,性能差劲)

class SingleInstance{
    SingleInstance singleInstance=null;
    private SingleInstance(){
        //构造方法私有化
    }

    public synchronized SingleInstance getSingleInstance() {
        return singleInstance;
    }
}
复制代码

4.双校验模式(推荐写法,需要注意的点比较多)

class SingleInstance{
    static volatile SingleInstance singleInstance=null;//注意volatile修饰
    private SingleInstance(){
        //构造方法私有化
    }

    public static SingleInstance getSingleInstance() {
        if(singleInstance==null){//第一次校验
            synchronized (SingleInstance.class){
                if(singleInstance==null)//第二次检验
                    singleInstance=new SingleInstance();
            }
        }
        return singleInstance;
    }
}
复制代码

volatile的功能不在本篇博客的介绍范畴内,可简单理解为多线程状态下可以让另一个线程感知到被volatile修饰的对象的变化,具体自行百度。

两次校验目的:

第一次:因为大部分情况下是不需要执行到synchronized代码块的,校验到不是null直接返回实例;

第二次:第一次校验成功后可能会处理机切换,导致创建出多个实例。

菜鸟教程上另外提供了内部类和枚举写法,这两种我暂时就不提供了,感觉对于内部类和枚举方式的还是不太习惯,没什么特殊需求写第四种就可以了,日后或许会补充,感谢阅读!