单例模式中的双锁机制,分别起到了什么作用
在单例模式的双重检查锁定(DCL,Double Checked Locking)机制中,涉及到两重 “锁” 相关的操作,各自有着重要作用。
首先是外层的同步锁,也就是synchronized
关键字修饰的代码块部分。它的主要作用是控制在多线程环境下,同一时刻只有一个线程能够进入到创建单例对象实例的关键代码区域。当多个线程同时调用getInstance
方法尝试获取单例对象时,这个锁能够避免多个线程同时去创建实例,防止出现创建出多个实例的情况,保证了在并发场景下实例创建的唯一性。例如,线程 A 和线程 B 同时执行到获取单例对象的方法处,线程 A 获取到外层的同步锁后进入代码块,此时线程 B 就只能等待线程 A 释放锁后才有机会进入,从而避免了它们同时去执行创建实例的操作。
而内层的判空检查,也就是在同步块内再次进行的if (instance == null)
判断。它的作用在于,虽然外层已经通过同步锁控制了同时只能有一个线程进入创建实例的代码块,但有可能在这个线程进入同步块前,已经有别的线程经过了外层判空检查且进入同步块创建好了实例。所以内层判空检查就是为了确保当线程进入到这个同步块内时,再次核实单例对象是否真的还没被创建,如果已经创建了就直接返回已有的实例,避免重复创建,进一步保证了单例对象创建的正确性和唯一性,优化了性能,避免了不必要的实例创建操作,提升了多线程环境下获取单例对象的效率。