设计模式系列——单例模式

215 阅读2分钟

原创:花括号MC(微信公众号:huakuohao-mc),欢迎分享,转载请保留出处。

单例模式顾名思义,就是保证系统中一个类只有一个唯一的对象实例。实际开发过程中经常会碰到这种需求。

单例模式有两种实现方式,一种称为饿汉式,一种称为懒汉式

先来看一下UML图:

single.png

饿汉式

之所以称为饿汉,是因为该种实现方式是在类被加载得时候就初始化对象,而且是通过JVM的类加载机制保证系统中只有一个类实例。

先看饿汉式的完整代码

public class SingleObject {

    //create an object  of SingleObject
    private static SingleObject instance = new SingleObject();

    //make the constuctor private so that this class cannot be instantiated
    private SingleObject(){}

    public static SingleObject getInstance(){
        return instance;
    }

    public void showMessage(){
       System.out.println("I'm eager");
    }
}

饿汉式的关键代码在第一行,通过static关键字修饰了instance变量了,这样在类被加载的时候就会初始化SingleObject

懒汉式

所谓的懒汉式就是在需要的时候在创建对象,懒汉式比较复杂,需要通过锁加双重检查机制来保障多线程环境下,只有一个实例被创建。 完整代码如下

public class LazySingleObject {

    private volatile static LazySingleObject instance = null;

    private LazySingleObject() {}

    public static LazySingleObject getInstance(){
        //第一重检查
        if (instance == null){
            synchronized (LazySingleObject.class){
               //第二重检查
                if (instance == null){
                    instance = new LazySingleObject();
                }
            }
        }
        return instance;
    }
    
    public void showMessage(){
        System.out.println("I'm lazy");
    }
    
}

这样使用单例模式

SingleObject object = SingleObject.getInstance();
//show the message
object.showMessage();

总结

单例模式也是创建型模式之一,实现该模式的时候都要把实例变量设置为静态的,其次构造函数都要变成私有的,防止在外部被引用并创建对象。饿汉式实现起来比较容易,但是初始化的实例对象比较耗时和占用资源的话,在系统启动时会比较浪费时间和资源;相反懒汉式则是在需要的时候进行初始化,不会占用系统启动资源,但是实现起来比较麻烦,特别是在多线程的场景下,除非有特殊要求,否则建议使用饿汉式。

推荐阅读

1. Java并发编程那些事儿(十)——最后的总结

2. 程序员应该掌握的常用网络问题定位工具

3. Awk这件上古神兵你会用了吗

4. 手把手教你搭建一套ELK日志搜索运维平台


wechat-search.png