google cache

来源:互联网 发布:蓝牙模块与单片机连接 编辑:程序博客网 时间:2024/06/16 02:06
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=4concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS);//Strength.STRONG默认为强引用keyStrength = builder.getKeyStrength();//Strength.STRONG默认为强引用valueStrength = builder.getValueStrength();//提供比较的工具和hash工具keyEquivalence = builder.getKeyEquivalence();valueEquivalence = builder.getValueEquivalence();//builder时设置的是500maxWeight = builder.getMaximumWeight();//得到OneWeigher,getWeigher=1weigher = builder.getWeigher();//expireAfterAccessNanos=0,未设置默认值为0expireAfterAccessNanos = 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_WRITEentryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries());//所有实现都是空方法globalStatsCounter = builder.getStatsCounterSupplier().get();//示例中的CacheLoaderdefaultLoader = loader;//总个数不能超过最大值,builder.getInitialCapacity()未设置,取默认值为16int 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=falsewhile (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,126createSegment(segmentSize, maxSegmentWeight, builder.getStatsCounterSupplier().get())//LocalCache,4,126new 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();    }
原创粉丝点击