`

WeakCache详解

 
阅读更多

WeakCache的作用看名字就知道,是一个缓存类,Weak指的是它的key和value是弱引用。jdk的动态代理就使用WeakCache存储代理类。

 

WeakCache<K,P,V>中,K代表key值,P代表参数,V代表存储的值。此类用于缓存{(key,sub-key)-->value}键值对。具体实现是一个ConcurrentMap<Object,ConcurrentMap<Object,Supplier<V>>>(Supplier是一个接口,就一个get方法用于获得值,不过是V的包裹类),第一个Object就是key(这里表达式不用K是因为key值可以为null),第二个Object就是sub-key。

这里就要问一下,WeakCache<K,P,V>中sub-key在哪?具体缓存实现里也没有P,那它用来干嘛?

这里又要介绍一个接口BiFunction<T,U,R>,我们用到它的R apply(T t,U u)方法,这个方法的意思就是根据T值和U值得到R值,具体实现自己定。其实就是方法的最简单逻辑给你参数根据参数计算得到结果。

WeakCache对象初始化时,需要传入两个BiFunction对象

 

public WeakCache(BiFunction<K, P, ?> subKeyFactory,
                     BiFunction<K, P, V> valueFactory) {
//根据K和P获得sub-key的算法
        this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
//根据K和P获得value的算法
        this.valueFactory = Objects.requireNonNull(valueFactory);
    }

 

 归根结底这个类只要弄懂它的public V get(K key,P parameter)方法就行了

 public V get(K key, P parameter) {
//Object工具类该方法参数为空抛出异常用于验证
        Objects.requireNonNull(parameter);
//将被clear的key值对应值从map中删除
        expungeStaleEntries();
//map中的key值和value值都是弱引用,这里valueOf静态方法,返回key的新建弱引用对象,
//这里有一点要注意CacheKey弱引用对象的hash值跟key值绑定,所以虽然新建了弱引用对象
//但是key值一样在map中就能取到对应的值
        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
//下面一段代码是如果key对应的二级map为空新建一个放进去,但是代码逻辑不是很清楚
//写是为了线程安全吗??
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // create subKey and retrieve the possible Supplier<V> stored by that
        // subKey from valuesMap
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue<V> instance
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
            // else no supplier in cache
            // or a supplier that returned null (could be a cleared CacheValue
            // or a Factory that wasn't successful in installing the CacheValue)

            // lazily construct a Factory
            if (factory == null) {
//Factory的get方法如果二级map中subkey对应的supplier是factory对象本身则根据key,parameter
//得到value值,生成弱引用并用这个弱引用替换掉二级引用中subkey对应的factory
                factory = new Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // successfully installed Factory
                    supplier = factory;
                }
                // else retry with winning supplier
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics