private LoadingCache cacheLoader;
public CacheUtils(final CacheService cacheService){
cacheLoader = CacheBuilder.newBuilder()
.maximumSize(500)
.expireAfterWrite(120, TimeUnit.MINUTES)
.refreshAfterWrite(1, TimeUnit.MINUTES)
.build(new CacheLoader(){
@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(this, loader);
创建LocalCache内部类LocalLoadingCache实现LoadingCache,主要通过LoadingCache的get(K key)方法获取Value值,实际也是调用LocalCache
super(new LocalCache(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.>discardingQueue()
: new ConcurrentLinkedQueue>();
//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(this, initialCapacity, maxSegmentWeight, statsCounter);
//上面调用的构造器
Segment(LocalCache map, int initialCapacity, long maxSegmentWeight,
StatsCounter statsCounter) {
this.map = map;//LocalCache
this.maxSegmentWeight = maxSegmentWeight;//126
this.statsCounter = checkNotNull(statsCounter);//记录
initTable(newEntryArray(initialCapacity));//new AtomicReferenceArray>(size);size=4,赋值到Entry的table属性
keyReferenceQueue = map.usesKeyReferences()//map.usesKeyReferences()是否不为强引用,false
? new ReferenceQueue() : null;//赋值为null
valueReferenceQueue = map.usesValueReferences()
? new ReferenceQueue() : null;//同上,赋值为null
recencyQueue = map.usesAccessQueue()//是否使用访问过期:false
? new ConcurrentLinkedQueue>()
: LocalCache.>discardingQueue();//空队列
writeQueue = map.usesWriteQueue()//是否使用写过期,创建写队列
? new WriteQueue()
: LocalCache.>discardingQueue();
accessQueue = map.usesAccessQueue()//是否使用访问过期,false
? new AccessQueue() //空队列
: LocalCache.>discardingQueue();
}