高效实现Map的原子更新操作(Hystrix的InternMap源码解析)

2017-01-13 14:58:39来源:csdn作者:tang9140人点击

第七城市

最近在学习Hystrix框架时,看到有一段代码,挺有意思的,代码如下:


代码清单1-1

public class InternMap<K, V> {
private final ConcurrentMap<K, V> storage = new ConcurrentHashMap<K, V>();
private final ValueConstructor<K, V> valueConstructor;public interface ValueConstructor<K, V> {
V create(K key);
}public V interned(K key) {
V existingKey = storage.get(key);
V newKey = null;
if (existingKey == null) {
newKey = valueConstructor.create(key);
existingKey = storage.putIfAbsent(key, newKey);
}
return existingKey != null ? existingKey : newKey;
}
}

省略了部分非关注代码……


ValueConstructor是函数式接口,作用是传入key获得value值,JDK8引入的新特性。



重点关注上面的interned方法:先是判断key对应的value是否已存在:如果不存在,则通过ValueConstructor产生新的value,并存入storage中。最后返回已存在的value


逻辑很简单,但是上面的代码却写得很复杂,感觉有点啰嗦,一般写法如下:


代码清单1-2

public V interned(K key) {
V existingValue = storage.get(key);
if (existingValue == null) {
existingValue = valueConstructor.create(key);
storage.put(key, existingValue);
}
return existingValue;
}仔细分析下上面简单写法,存在着线程安全问题。由于未进行同步处理,可能出现两个线程同时进入if语句块,从而导致每个线程获得了不同的existingValue,这显然是不希望看到的。


再回过头来看代码1-1,就明白作者的深意了。通过ConcurrentHashMap提供的线程安全的putIfAbsent方法,保证了storage存入时的线程安全,同时通过对newKey、existingKey(实际上应该取名为newValue、existingVaule)两个线程内变量值判断进行返回,保证了整个方法操作的原子性。


这种实现线程安全的方式,没有用同步代码块等比较低效的同步方式,确实是一种高效实现Map的原子更新方式,不得不为作者的深思熟虑感到佩服.......



最后,我想问句:元芳,你怎么看?

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台