最近在看dubbo的源代码,发现dubbo类ExtensionLoader中有一段代码:
private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<Class<?>, ExtensionLoader<?>>();
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
if (type == null)
throw new IllegalArgumentException("Extension type == null");
if(!type.isInterface()) {
throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
}
if(!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type(" + type +
") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
}
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
if (loader == null) {
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
return loader;
}
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
不明白作者这段代码的用意,为什么不如下面这么写:
loader = new ExtensionLoader<T>(type);
EXTENSION_LOADERS.putIfAbsent(type,loader);
这么写的玄机是什么?
不用这里写法,是为了保证取的对象是同一个
putIfAbsent是key存在就不替换,这里return回去的都是从map里get出来的,而不是new出来的
对构造函数的封装,使用并发的ConcurrentHashMap实现多线程下的单例模式