常见的几种单例模式

今天面试官问到单例模式有哪几种,

我一下子愣了,虽然简单看过单例模式,但是还真不清楚的了解到它还有哪些类型。

今天决定学习一下。

单例模式是一种常用的软件设计模式,在它的核心结构中值包含一个被称为单例的特殊类。一个类只有一个实例,即一个类只有一个对象实例。为了减少重复创建实例造成内存浪费。应用的场景如:每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求同时调用。

单例模式可以分为懒汉式和饿汉式

    懒汉式单例模式:在类加载时不初始化。

    饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。

懒汉式单例:

/**
 * 这个是懒汉模式,并且线程非安全
 */
public class SingletonDemo1 {

    private static SingletonDemo1 instance;

    private SingletonDemo1() {

    }

    public static SingletonDemo1 getInstance() {
        // 若当前实例为空,重新创建内存指向一个新的实例
        if (instance == null) {
            instance = new SingletonDemo1();

        }
        return instance;
    }
}

上面那个懒汉模式有个问题就是线程不安全:因此可以加上 synchronized 关键字保证线程安全

/**
 * 这个是懒汉模式,线程安全的
 */
public class SingletonDemo2 {

    private static SingletonDemo2 instance;

    private SingletonDemo2() {

    }

    // 加上 synchronized 保证创建线程线程安全
    public static synchronized SingletonDemo2 getInstance() {
        // 若当前实例为空,重新指向一个新的实例
        if (instance == null) {
            instance = new SingletonDemo2();

        }
        return instance;
    }
}

接下来是饿汉模式,字面意思理解起来就是饥渴的,迫切需要的,即类加载时就要初始化

/**
 * 这个是饿汉模式,类一加载就要初始化
 */
public class SingletonDemo3 {

    // 在成员变量声明的时候就要初始化
    private static SingletonDemo3 instance = new SingletonDemo3();

    private SingletonDemo3() {

    }


    public static SingletonDemo3 getInstance() {
        // 若当前实例为空,重新指向一个新的实例
        if (instance == null) {
            instance = new SingletonDemo3();

        }
        return instance;
    }
}

接下来, 静态内部类这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟前几种方式不同的是:Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比饿汉方法就显得更合理。

/**
 * 这个是懒汉模式变种,使用静态内部类创建
 */
public class SingletonDemo4 {

    private static class SingletonHolder{
        private static final SingletonDemo4 instance = new SingletonDemo4();
    }

    private SingletonDemo4() {

    }


    public static SingletonDemo4 getInstance() {
        // 调用内部类的属性创建新的实例
        return SingletonHolder.instance;
    }
}
原文地址:https://www.cnblogs.com/libera11/p/9174014.html