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

最近在学习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的原子更新方式,不得不为作者的深思熟虑感到佩服.......


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

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值