单例模式(懒汉式-饿汉式)

62 阅读2分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 十二 天,点击查看活动详情

单例模式

懒汉式

image.png

这里测试打印

image.png
这里有个问题是为什么打印输出时把this换成instance就不行了呢

image.png

image.png 仅仅输出null。

image.png 打印发现先执行getInstance实力创建方法,然后执行静态构造器。 显然我们创建的这个实例是静态的,放在方法区,但其实静态变量创建多次在堆中也只有一个对象,等于你创建多个类他们有多个实例但指向的是共用一个静态变量实例,使用单例模式等于一个类只允许有一个实例。 类中的静态引用指向jvm堆中的实例对象,那么此实例就不会被回收。 所以这里应该是创建的实例对象没有赋给静态引用instance,查看逻辑发现确实如此。

image.png 那么现在将实例对象赋给引用,发现必须在new instance之后才可以拿到instance值,

image.png

逻辑

通过调用类的静态方法执行其方法,先判断实例是否为null,这里显然第一次创建肯定会执行此判断语句,所以这里new Singleton(),new对象时会执行类的构造函数,但执行构造函数时,静态引用还是null,但是this是有值的,this就指代构造函数创建的实例,然后我们将实例赋给instance,instance就可以拿取到值,然后返回此实例。

image.png 构造函数私有,测试类就无法new Singleton(),无法执行其构造函数。

懒汉式

public class Singleton {
    private static Singleton instance;
    private Singleton (){
        System.out.println("正在创建单例模式" + instance);
    };

    public static synchronized Singleton getInstance() {
        System.out.println("开始判断过程");
        if(instance == null){
            System.out.println("即将开始创建" + instance);
            instance = new Singleton();
        }
        System.out.println("创建了" + instance);
        return instance;
    }
}

饿汉式

public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton (){};

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