之前看了一下梁飞的天猫并发手册,记录一下 low cost 的缓存的并发代码如下
class Item { volatile Object value; Object get() {…} set(Object value) {…} }
ConcurrentMap cache = new ConcurrentHashMap();
item = cache.get(key);
if (item == null) {
//这里可以看到用了并发容器之后就没有加锁的操作
item = new Item();
oldItem = cache.putIfAbsent(key, item);
if (oldItem != null) {
item = oldItem;
}
}
value = item.get();
if (value == null) {
synchronized(item) {
value = item.get();
if (value == null) {
value = load(key);
item.set(value);
}
}
}
看到以上段代码我心中突然浮现了一段灰常相似的一段代码如下:
*
* @param configPath - config path
* @param configProperties - config properties
* @return template engine
*/
public static Engine getEngine(String configPath, Properties configProperties) {
if (StringUtils.isEmpty(configPath)) {
configPath = HTTL_PROPERTIES;
}
//这里的ENGINES就是一个ConcurrentMap
VolatileReference<Engine> reference = ENGINES.get(configPath);
if (reference == null) {
reference = new VolatileReference<Engine>(); // quickly
VolatileReference<Engine> old = ENGINES.putIfAbsent(configPath, reference);
if (old != null) { // duplicate
reference = old;
}
}
assert (reference != null);
Engine engine = reference.get();
if (engine == null) {
synchronized (reference) { // reference lock
engine = reference.get();
if (engine == null) { // double check
engine = BeanFactory.createBean(Engine.class, initProperties(configPath, configProperties)); // slowly
reference.set(engine);
}
}
}
assert (engine != null);
return engine;
}
以上代码来自梁飞的开源模板引擎HTTL的Engine核心类里边对模板引擎实例的缓存~ ~ !
其中的VolatileReference类其实和第一短代码中的
貌似又雷同了 。。。
此段缓存代码涉及到运用了MESI协议(CPU缓存一致性协议,白话一点就是volatile关键字的使用)和并发容器的处理