Guava缓存器源码分析——键值类型

      昨天分析了Guava缓存器的数据存取过程,下面介绍下键值类型所涉及的类图:
       
        Guava缓存器中键值都通过工厂模式来创建,工厂类型为枚举变量,包括以下8种:STRONG, STRONG_ACCESS, STRONG_WRITE, STRONG_ACCESS_WRITE, WEAK, WEAK_ACCESS, WEAK_WRITE, WEAK_ACCESS_WRITE ,存放在EntryFactory数组中。
        构造缓存器时,初始化键值工厂:
        entryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries());
        其中,keyStrength为键的引用级别, 将usesAccessEntries()可展开为 expireAfterAccessNanos > 0 || maxWeight >= 0,表示设置了访问过期时间或权重参数,usesWriteEntries()可展开为expireAfterWriteNanos > 0 || refreshNanos > 0,表示设置了写过期时间或刷新时间。
         键值工厂的获取:
            static EntryFactory getFactory(Strength keyStrength, boolean usesAccessQueue,
                                                                        boolean usesWriteQueue) {
                          int flags = ((keyStrength == Strength.WEAK) ? WEAK_MASK : 0)
                                              | (usesAccessQueue ? ACCESS_MASK : 0)
                                              | (usesWriteQueue ? WRITE_MASK : 0);
                          return factories[flags];
                    }
           每种工厂都有各自的newEntry方法,默认引用级别下,newEntry方法产生的键值引用为StrongEntry类型。
             STRONG {
              @Override
               <K, V> ReferenceEntry<K, V> newEntry(
                    Segment<K, V> segment, K key, int hash, @Nullable ReferenceEntry<K, V> next) {
                    return new StrongEntry<K, V>(key, hash, next);
              }
         }
       
       强引用级别的缓存数据,将直接存储缓存键的引用,其它级别的缓存数据,将缓存键的引用委托给它们的父类。

       在查询数据时,如果需要加载数据(不存在或过期),首先会创建LoadingValueReference类型的值引用,若数据不存在,则需要创建并初始化新的键值引用(newEntry()),若数据过期只需要重新设置值引用即可:setValueReference(loadingValueReference);
       
       实际的数据加载是通过调用LoadingValueReference类的loadFuture方法,该方法会调用缓存器构建时用户自定义的数据加载方法load() || reload(),并通过Stopwatch记录数据加载时间。

        Guava缓存器中涉及到键值的底层操作都通过Unsafe类来实现,Unsafe类提供了硬件级别的原子操作,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
        例如:
        public final boolean compareAndSet(int i, E expect, E update) {
               return unsafe.compareAndSwapObject(array, rawIndex(i), expect, update);
        }
        该方法在array的 rawIndex(i)位置比较object field和期望的值expect,如果相同则更新为update。
        这里顺便介绍下Compare And Swap(CAS)操作:CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值