google cache

private LoadingCache<K, V> cacheLoader;
public CacheUtils(final CacheService<K,V> cacheService){
        cacheLoader = CacheBuilder.newBuilder()
                        .maximumSize(500)
                .expireAfterWrite(120, TimeUnit.MINUTES)
                .refreshAfterWrite(1, TimeUnit.MINUTES)
                .build(new CacheLoader<K, V>(){
                    @Override
                    public V load(K key) {
                        return cacheService.loadDataByKey(key);
                    }
                });
}

通过CacheBuilder创建LoadingCache,首先复制需要初始化的属性,build方法创建,放入CacheLoader,实现load方法,主要当通过key获取不到value的值,通过此load方法再次获取。
CacheBuilder.newBuilder()

  public static CacheBuilder<Object, Object> newBuilder() {
    return new CacheBuilder<Object, Object>();
  }
  CacheBuilder() {}构造方法为一个空方法
maximumSize(500)
cache存储最大值为500
初始化值为this.maximumSize = size;//500
expireAfterWrite(120, TimeUnit.MINUTES)//写入超过120分钟过期
this.expireAfterWriteNanos = unit.toNanos(duration);转换为纳秒
refreshAfterWrite(1, TimeUnit.MINUTES)//写入一分钟后刷新
this.refreshNanos = unit.toNanos(duration);转换为纳秒
build(new CacheLoader<K, V>(){}
当key没有值时,用CacheLoader加载
new LocalCache.LocalLoadingCache<K1, V1>(this, loader);
创建LocalCache内部类LocalLoadingCache实现LoadingCache,主要通过LoadingCache的get(K key)方法获取Value值,实际也是调用LocalCache
super(new LocalCache<K, V>(builder, checkNotNull(loader)));
构造方法中也是调用父类的构造方法创建LocalCache当做参数,放入到LoadingCache中,主要就是创建LocalCache
//得到segment大小,从例子中没有设置则取默认值4,concurrencyLevel=4
concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS);
//Strength.STRONG默认为强引用
keyStrength = builder.getKeyStrength();
//Strength.STRONG默认为强引用
valueStrength = builder.getValueStrength();
//提供比较的工具和hash工具
keyEquivalence = builder.getKeyEquivalence();
valueEquivalence = builder.getValueEquivalence();
//builder时设置的是500
maxWeight = builder.getMaximumWeight();
//得到OneWeigher,getWeigher=1
weigher = builder.getWeigher();
//expireAfterAccessNanos=0,未设置默认值为0
expireAfterAccessNanos = builder.getExpireAfterAccessNanos();
//120分钟的纳秒
expireAfterWriteNanos = builder.getExpireAfterWriteNanos();
//1分钟的纳秒
refreshNanos = builder.getRefreshNanos();
//移除数据的监听器
removalListener = builder.getRemovalListener();
//得到返回数据为空的队列
removalNotificationQueue = (removalListener == NullListener.INSTANCE)
        ? LocalCache.<RemovalNotification<K, V>>discardingQueue()
        : new ConcurrentLinkedQueue<RemovalNotification<K, V>>();
//recordsTime()是否记录时间,判断是否有设置访问时间,写时间,过期时间
//ticker.read()得到系统时间
ticker = builder.getTicker(recordsTime());
//flags=0|1|2=0|1|10=11=3,所以entryFactory=STRONG_WRITE
entryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries());
//所有实现都是空方法
globalStatsCounter = builder.getStatsCounterSupplier().get();
//示例中的CacheLoader
defaultLoader = loader;
//总个数不能超过最大值,builder.getInitialCapacity()未设置,取默认值为16
int initialCapacity = Math.min(builder.getInitialCapacity(), MAXIMUM_CAPACITY);、
//evictsBySize():maxWeight >= 0:true;
//!customWeigher():weigher!=OneWeigher.INSTANCE:true;
//initialCapacity=16最后值
if (evictsBySize() && !customWeigher()) {
     initialCapacity = Math.min(initialCapacity, (int) maxWeight);
}
int segmentShift = 0;
//seqment的个数
int segmentCount = 1;
//当segmentCount小于设置的最低concurrencyLevel个数,而且数量乘以20还小于最大数量则可以增加seqment的值
//每次以2的幂增加,1<<1,2的1次幂,1<<2,2的2次幂,移动2次就已经够用4<4=false
while (segmentCount < concurrencyLevel
           && (!evictsBySize() || segmentCount * 20 <= maxWeight)) {
      ++segmentShift;
      segmentCount <<= 1;
    }
    //segmentShift=2
    //this.segmentShift=30
    this.segmentShift = 32 - segmentShift;
    //segmentMask=3
    segmentMask = segmentCount - 1;
    //new Segment[ssize];ssize=4
    this.segments = newSegmentArray(segmentCount);
    //segmentCapacity=16/4=4
    int segmentCapacity = initialCapacity / segmentCount;
    if (segmentCapacity * segmentCount < initialCapacity) {
      ++segmentCapacity;
    }
    //segmentCapacity=4
    int segmentSize = 1;
    //跟segmentCount初始化方式一样,按2的幂次结算
    while (segmentSize < segmentCapacity) {
      segmentSize <<= 1;
    }
    //segmentSize=4
    //evictsBySize():true,maxWeight>0:500>0=true
    if (evictsBySize()) {
      //maxSegmentWeight=500/4+1=126
      long maxSegmentWeight = maxWeight / segmentCount + 1;
      //remainder=500%4=125
      long remainder = maxWeight % segmentCount;
      //为每一个seqment赋值
      for (int i = 0; i < this.segments.length; ++i) {
        if (i == remainder) {
          maxSegmentWeight--;
        }
        //所有的maxSegmentWeight=126
        this.segments[i] =
            //对seqment赋值
            createSegment(segmentSize, maxSegmentWeight, builder.getStatsCounterSupplier().get());
      }
    } else {
      for (int i = 0; i < this.segments.length; ++i) {
        this.segments[i] =
            createSegment(segmentSize, UNSET_INT, builder.getStatsCounterSupplier().get());
      }
    }
//4,126
createSegment(segmentSize, maxSegmentWeight, builder.getStatsCounterSupplier().get())
//LocalCache,4,126
new Segment<K, V>(this, initialCapacity, maxSegmentWeight, statsCounter);
//上面调用的构造器
Segment(LocalCache<K, V> map, int initialCapacity, long maxSegmentWeight,
        StatsCounter statsCounter) {
      this.map = map;//LocalCache
      this.maxSegmentWeight = maxSegmentWeight;//126
      this.statsCounter = checkNotNull(statsCounter);//记录
      initTable(newEntryArray(initialCapacity));//new AtomicReferenceArray<ReferenceEntry<K, V>>(size);size=4,赋值到Entry的table属性
      keyReferenceQueue = map.usesKeyReferences()//map.usesKeyReferences()是否不为强引用,false
           ? new ReferenceQueue<K>() : null;//赋值为null

      valueReferenceQueue = map.usesValueReferences()
           ? new ReferenceQueue<V>() : null;//同上,赋值为null

      recencyQueue = map.usesAccessQueue()//是否使用访问过期:false
          ? new ConcurrentLinkedQueue<ReferenceEntry<K, V>>()
          : LocalCache.<ReferenceEntry<K, V>>discardingQueue();//空队列

      writeQueue = map.usesWriteQueue()//是否使用写过期,创建写队列
          ? new WriteQueue<K, V>()
          : LocalCache.<ReferenceEntry<K, V>>discardingQueue();

      accessQueue = map.usesAccessQueue()//是否使用访问过期,false
          ? new AccessQueue<K, V>()      //空队列
          : LocalCache.<ReferenceEntry<K, V>>discardingQueue();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值