单例模式看这几个

单例模式是一种常用的软件设计模式,通过它能够保证系统中,应用该模式的一个类只有一个实例。

在面试中,本人总共手写过三种单例模式:懒汉模式、饿汉模式、双重检查模式

懒汉模式:顾名思义,当系统需要类的实例的时候才会进行初始化,否则就不会进行初始化。

public class Singleton {
    private static Singleton singleton = null;

    private Singleton() {}

    public synchronized static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

饿汉模式:饿汉就是无论系统需不需要,都会准备好该实例

public class Singleton {
	private final static Singleton singleton = new Sinleton();
	private Singleton() {}
	public static Singleton getInstance() {
		return singleton;
	}
}

双重检查模式:

public class Singleton {
    private volatile static Singleton singleton = null;
    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

这个代码就像进门一样,那么你先推开门看看是否可以打开,如果可以打开的话,那么你就进去,然后上锁,最后在检查一遍是否锁好。

但是本人觉得这个双重检查的重心应该实在 volatile 关键字上,如果没有加 volatile 关键字,那么在多线程的环境下就可能会调用失败。

参考:https://blog.csdn.net/xiaobudian0381/article/details/91403670

一个类进行实例化的时候简单的来说要进行三步:

  1. 分配内存空间
  2. 初始化对象
  3. 返回该对象的地址

在第二步和第三步中不存在依赖关系,所以可能会发生指令重排的事情,举例说明:A线程调用 getInstance() 方法,发生了指令重排(第二步 第三部 颠倒),先返回的是该对象的地址。此时,线程B调用 getInstance() 方法,发现 singleton 不是空,直接返回。问题出现了,A线程实例化的时候仅仅返回的是对象的地址,但是并没有进行初始化,但是线程B不知道,所以出现了错误。

但是加了 volatile 关键字就可以避免这种情况。关于其他的 volatile 关键字的讲解,可以参考:

https://blog.csdn.net/xiaobudian0381/article/details/90897800

https://blog.csdn.net/xiaobudian0381/article/details/91348251

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值