上一節提到緩存中的實體類是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的相對應