设计模式01——单例模式(懒汉和饿汉)

226 阅读2分钟

单例模式介绍

单例模式:单例模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。单例模式能够保证某一类型对象在系统中的唯一性,即某类在系统中只有一个实例。

单例模式中的两种模式介绍

1.懒汉模式:顾名思义,他是一个懒汉,不愿动弹。只有你主动叫他的时候他才会工作,也就是说实例在类加载的时候不被初始化,到了需要使用的时候才会进行初始化。

2.饿汉模式:顾名思义,他是一个饿汉,他很勤快就怕自己饿着。他总是先把食物准备好,什么时候需要吃了,他随时拿来吃,不需要临时去搞食物。因此饿汉模式下实例在类加载时就完成了初始化,但是加载比较慢,获取对象比较快。

懒汉模式代码实现

public class LazybonesSingleton {
    //默认不会实例化,什么时候用就什么时候new
    private static LazybonesSingleton instance = null;

    private LazybonesSingleton() {

    }

    public static LazybonesSingleton getInstance() {
        if (instance == null) {
            //什么时候用就什么时候new
            synchronized (LazybonesSingleton.class) {
                //使用双检查机制确保instance不为空时候只会被同步锁一次,减少使用锁的消耗,
                //而且保证instance只会被new一次,
                if (instance == null) {
                    instance = new LazybonesSingleton();
                }
            }
        }
        return instance;
    }
}

饿汉模式代码实现

public class HungrySingleton {
    //一开始类加载的时候就进行实例化,创建单实例对象
    private static HungrySingleton instance = new HungrySingleton();
    private HungrySingleton(){

    }
    public static HungrySingleton getInstance(){
        return instance;
    }
}

单例中懒汉和饿汉的区别

(1) 线程安全:饿汉式在线程还没出现之前就已经实例化了,所以饿汉式一定是线程安全的。懒汉式加载是在使用时才会去new实例的,那么你去new的时候是一个动态的过程,因此在new需要使用一些机制去保证创建实例时候的线程安全,例如上面代码所使用的同步锁+双检查机制。

(2)执行效率:饿汉式没有加任何的锁,因此执行效率比较高。懒汉式一般使用都会加同步锁,效率比饿汉式差。

(3)内存使用:饿汉式在一开始类加载的时候就实例化,无论使用与否,都会实例化,所以会占据空间,浪费内存。懒汉式什么时候用就什么时候实例化,不浪费内存。