大家好,我是有庆
一位名人曾说过:检查对象一次是不够的,必须检查两次
据这位名人所说,很多框架都是使用双重检查锁来获取对象的
例如Nacos的InstancesChangeNotifier类中,eventListeners对象的获取
private finalMap> listenerMap = new并发HashMap >();
私人 Final 对象锁= new Object();
publicvoidregisterListener (字符串组名称、字符串服务名称、字符串集群、EventListener侦听器) {
String key = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), clusters);
ConcurrentHashSet eventListeners = ListenerMap.get(key);
if(事件监听器 == null) {
同步(锁定){
eventListeners = listenerMap.get(key);
if(事件监听器 == null) {
事件监听器 = newCon currentHashSet();
listenerMap.put(key, eventListeners);
}
}
}
eventListeners.add(监听器);
}
再或者在春天获取单例豆的时候
受保护对象getSingleton(字符串beanName,布尔值允许早期参考){
//快速检查现有实例,无需完整实例单例锁
对象 singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
唱letonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
同步(这个.singletonObjects){
//在完整单例锁内一致创建早期引用
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if(singletonObject == null) {
ObjectFactory> singletonFactory = this.s ingletonFactories.get(beanName);
if(singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
这个.singletonFactories.remove(beanName);
}
}
}
} }
}
return singletonObject;
}
通过上面两个例子再结合双重检查锁的这个名字
我们难免出门,双重检查锁,就是判断一个对象在不在,不在的话,先锁住这个对象,再判断一次在不在,不在就开始加载这个对象
那么为什么框架都喜欢使用这种双重检查锁的模式去获取Bean?它的优势在哪里?一步一步看👇