多线程环境下单例模式的一种实现方式

最近在看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;
    }

不用这里写法,是为了保证取的对象是同一个

putIfAbsent是key存在就不替换,这里return回去的都是从map里get出来的,而不是new出来的

对构造函数的封装,使用并发的ConcurrentHashMap实现多线程下的单例模式

最近在看dubbo的源代码,发现dubbo类ExtensionLoader中有一段代码: private static final ConcurrentMap , ExtensionLoader > EXTENSION_LOADERS = new ConcurrentHashMap , ExtensionLoader >(); public static ExtensionLoader getExtensionLoader(Class 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 loader = (ExtensionLoader ) EXTENSION_LOADERS.get(type); if (loader == null) { EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader (type)); loader = (ExtensionLoader ) EXTENSION_LOADERS.get(type); } return loader; } 不用这里写法,是为了保证取的对象是同一个 putIfAbsent是key存在就不替换,这里return回去的都是从map里get出来的,而不是new出来的 对构造函数的封装,使用并发的ConcurrentHashMap实现多线程下的单例模式
经验分享 程序员 微信小程序 职场和发展