上一节提到缓存中的实体类是ReferenceEntry{K, V>(key可以是任意的类型,value是ValueReference{K, V>),但是它只是个接口,下图是他的实现
创建方式
这个是在Segment类里,map 是LocalCache.
ReferenceEntry<K, V> newEntry(K key, int hash, @Nullable ReferenceEntry<K, V> next) {
return map.entryFactory.newEntry(this, checkNotNull(key), hash, next);
}
而entryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries());
1. keyStrength : 默认是Strength.STRONG,还有SOFT和WEAK
enum EntryFactory {
STRONG -- new StrongEntry<K, V>(key, hash, next),
.....
static final EntryFactory[] factories = {
STRONG, STRONG_ACCESS, STRONG_WRITE, STRONG_ACCESS_WRITE,
WEAK, WEAK_ACCESS, WEAK_WRITE, WEAK_ACCESS_WRITE,
};
//提供具体的实体类
static EntryFactory getFactory(Strength keyStrength, boolean usesAccessQueue,
boolean usesWriteQueue) {
int flags = ((keyStrength == Strength.WEAK) ? 4: 0)
| (usesAccessQueue ? 1: 0)
| (usesWriteQueue ? 2: 0);
return factories[flags];
}
- AbstractReferenceEntry :所有的方法都是抛出异常
public ValueReference<K, V> getValueReference() {
throw new UnsupportedOperationException();
}
public void setValueReference(ValueReference<K, V> valueReference) {
throw new UnsupportedOperationException();
}
...//都是抛出异常,所以这个类没有实际意义
1. StrongEntry : 提供key,value,hash,nxt
final K key;
final int hash;
final ReferenceEntry<K, V> next;//就是每次插入的
volatile ValueReference<K, V> valueReference = unset();
1.1 StrongAccessEntry : 访问的实体类,访问时间,前一个和后一个访问的节点
volatile long accessTime = Long.MAX_VALUE
ReferenceEntry<K, V> nextAccess = nullEntry();
ReferenceEntry<K, V> previousAccess = nullEntry();
1.2 StrongWriteEntry :写入的实体类,写入时间,前一个和后一个写入的节点
volatile long writeTime = Long.MAX_VALUE;
ReferenceEntry<K, V> nextWrite = nullEntry();
ReferenceEntry<K, V> previousWrite = nullEntry();
1.3 StrongAccessWriteEntry : 以上的 1.1和1.2 的所有属性都有
WeakEntry : 除了hash,next,valueReference 其余方法都是抛出异常
这个实现WeakReference,采用了弱引用,再没有引用时即会被垃圾回收
class WeakEntry<K, V> extends WeakReference<K> implements ReferenceEntry<K, V> {
final int hash;
final ReferenceEntry<K, V> next;
volatile ValueReference<K, V> valueReference = unset();
public void setPreviousInWriteQueue(ReferenceEntry<K, V> previous) {
throw new UnsupportedOperationException();
}
.....
}
其余几个方法和Strong的相对应