懒汉设计模式使用 volatile 关键字和两个 if 判断的原因

本文详细解析了Java中的懒汉设计模式实现单例,解释了为何使用volatile关键字以及双重检查锁定(double-checked locking)的重要性。通过外层和内层if判断确保线程安全,避免多个实例的创建。volatile关键字保证了内存可见性,防止线程在缓存中读取旧的数据。这种设计模式在保证单例的同时,也提高了效率。
摘要由CSDN通过智能技术生成

懒汉设计模式

代码

class Singleton {
    // 3. 加 volatile 关键字
    volatile private static Singleton instance = null;


    public static Singleton getInstance() {
    	// 2. 外层判断
        if (instance == null) {
        	// 1. 内层加锁判断
			synchronized (Singleton.class) {
				if (instance == null) {				
					instance = new Singleton();
				}
			}
		}
    }

    private Singleton() {

    }
}

为什么使用 volatile 和两个 if 判断?

  1. 内层加锁判断:在内层中加了 synchronized 锁判断 if (instance == null) ,是为了 防止 两个线程在同一时间调用 getInstance() , 然后判断结果为实例都为 null,从而导致两个线程都创建了实例;
  2. 外层判断:而外层 if (instance == null) 则是防止之后其他线程创建连接都需要加锁进行判断,线程之间的执行方式变成了串行, 时间效率大大变低。因此直接先判断 instance == null ,如果不等于 null,也就说之前已经创建过了实例,那么 直接返回实例
  3. 加 volatile 关键字:根据 2. 外层判断 中得知,如果开始有线程创建实例后,那么后续的线程只需要判断第一层循环即可,因为开始有线程已经把 instance 实例对象写入到内存了。
    但是还是存在一个问题,如果后续线程在 cpu 执行的时候,直接到 cpu 的寄存器查找 instance,判断其是否为 null,发现还是 null,那么就进入内层判断(当然,进入内层的判断是 synchronized 修饰的,已经保证了内存的可见性,因此不会创建新的 instance 实例),这就是内存可见性的问题。因此需要在 instance 对象前加 volatile 关键字保证内存可见性!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值