以下代码摘选自 Dubbo 框架的 ExtensionLoader, 非常有趣:
/* ExtensionLoader */
@SuppressWarnings(“unchecked”)
public T getLoadedExtension(String name) {
if (name == null || name.length() == 0)
throw new IllegalArgumentException(“Extension name == null”);
Holder<Object> holder = cachedInstances.get(name);
if (holder == null) {
cachedInstances.putIfAbsent(name, new Holder<Object>());
holder = cachedInstances.get(name);
}
return (T) holder.get();
}
/* Just a volatile-helper */
public class Holder<T> {
private volatile T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
可以看到, 精华就是 Holder-volatile 和双重 null 校验的运用;
短短几句代码, 蕴含了:
volatile 关键字的 happens-before 关系
volatile 关键字的可见性问题
Java 多线程的执行路径问题, 及指令重排序的问题;
(有兴趣的可自行查阅相关资料, 毕竟上述任意一个都是非常繁杂的话题)
这基本上可以作为最佳实践放入自己项目中的多线程模块中了, 在此仅做个记录;