懒汉单例模式下的双检锁机制解析

双检锁机制用于懒汉式单例模式,确保在多线程环境中只有一个Singleton实例。它通过两次检查uniqueInstance是否为null,并在必要时同步创建实例,避免性能开销。volatile关键字确保变量在多线程环境的可见性,防止创建多个实例。此机制在首次创建对象时使用锁,后续访问则无需加锁,提高了效率。

懒汉单例模式下的双检锁机制解析

我在学习懒汉式单例模式时,发现了懒汉双检锁的实现方式,当时不是很理解,查阅资料后得出以下结论

双检锁机制

在多个线程同时请求一个获取一个懒汉式单例对象时,可能会导致创建多个对象的问题,为了确保只有一个对象被创建,可以使用双检锁机制。(双检锁机制不是创建两个锁实现,而是再方法内部实现两种检锁)

​双检锁机制基于懒汉模式,在第一次获取单例对象时才创建它;

​为了提高程序的性能,我们不在方法前使用syschronized关键字,而是在方法内部使用,同时也形成了一个双重检查锁定机制。

示例代码

public class Singleton {
    private volatile static Singleton uniqueInstance;
    private Singleton() {}
     public static Singleton getInstance() {
         //第一重检锁
        if (uniqueInstance == null) {
            //第二重检锁,只有uniqueInstance为null时才会生效
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

​在双检锁机制中,我们使用了synchronized关键字来创建一个锁,确保只有一个线程能进入if语句块内部。在此之前,我们首先检查uniqueInstance变量是否为null。如果为null我们才进入if语句块,获取锁,并再次检查uniqueInstance变量是否为null。这是因为在多线程环境下,可能会有多个线程同时进入第一个if语句块,如果不在此检查uniqueInstance变量是否为null,就有可能会创建多个Singleton对象,违反了单例模式的原则。

​一旦我们进入了if语句块,获取了锁,就可以创建唯一的Singleton对象。其他线程尝试进入if语句块时,由于uniqueInstance变量已经不为null,所以它们不会执行if语句块内的代码,而是直接返回uniqueInstance变量的值。

​在整个过程中,synchronized关键字可以确保只有一个线程能够访问if一句话内的代码,在这之前和之后,uniqueInstance变量由于是用volatile关键字进行了修饰,可以被确保它在多线程环境下的可见性,从而避免了问题的发生。

补充

​除了在实现单例模式中使用双检锁机制之外,它还可以用于其他需要保证线程安全的场景。例如,我们可以使用双检锁机制来确保在多线程环境下只创建一个实例化某个对象的方法。
​双检锁机制在多线程环境下会有比较好的性能表现,因为它只在第一次创建对象时使用synchronized关键字来获取锁,在之后的访问中不需要获取锁,因此避免了不必要的开销。如果在多线程环境下需要频繁创建对象,使用双检锁机制会比使用简单的synchronized关键字更加高效。
​需要注意的是,虽然双检锁机制可以确保在多线程环境下只创建一个对象,但是如果对象的初始化操作耗时较长,可能会造成性能问题。此外,还需要注意正确使用volatile关键字,确保变量的可见性。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值