Mybatis的這兩個緩存裝飾器不要忽略
這篇文章繼續介紹聊聊Mybatis的緩存的其他裝飾者
引用的緩存裝飾器
SoftCache是軟引用的緩存裝飾器,軟引用就是在JVM記憶體不足的時候,軟引用的對象會被垃圾回收器回收,軟引用對象SoftReference可以關聯ReferenceQueue引用隊列,當對象被回收的時候,會通知引用隊列對象被回收了。
内部成員
SoftCache類中定義了一個内部類SoftEntry:
private static class SoftEntry extends SoftReference<Object> {
private final Object key;
SoftEntry(Object key, Object value, ReferenceQueue<Object> garbageCollectionQueue) {
super(value, garbageCollectionQueue);
this.key = key;
}
}
它繼承了SoftReference,設定key為強引用,value為軟引用,并設定引用隊列garbageCollectionQueue
放置元素
看一下SoftCache類的putObject()方法:
@Override
public void putObject(Object key, Object value) {
removeGarbageCollectedItems();
delegate.putObject(key, new SoftEntry(key, value, queueOfGarbageCollectedEntries));
}
private void removeGarbageCollectedItems() {
SoftEntry sv;
while ((sv = (SoftEntry) queueOfGarbageCollectedEntries.poll()) != null) {
delegate.removeObject(sv.key);
}
}
- 調用removeGarbageCollectedItems()方法,這個方法是周遊queueOfGarbageCollectedEntries記錄的被垃圾回收器回收value對象對應的key,然後從被裝飾器中删除緩存
- 調用被裝飾器放入緩存
擷取元素
從SoftCache類的getObject()方法可以看出:
@Override
public Object getObject(Object key) {
Object result = null;
@SuppressWarnings("unchecked") // assumed delegate cache is totally managed by this cache
SoftReference<Object> softReference = (SoftReference<Object>) delegate.getObject(key);
if (softReference != null) {
result = softReference.get();
if (result == null) {
delegate.removeObject(key);
} else {
// See #586 (and #335) modifications need more than a read lock
synchronized (hardLinksToAvoidGarbageCollection) {
hardLinksToAvoidGarbageCollection.addFirst(result);
if (hardLinksToAvoidGarbageCollection.size() > numberOfHardLinks) {
hardLinksToAvoidGarbageCollection.removeLast();
}
}
}
}
return result;
}
- 軟引用中記錄了這個key,對應value軟引用中沒有了就調用被裝飾器删除對應的緩存
- 把用到的value值放入LinkedList頭部中,這樣value就是強引用了,不會被垃圾回收器回收,預設放入256個,超出就删除尾部的
- 傳回value值
弱引用緩存裝飾器
WeakCache是弱引用緩存裝飾器,它的代碼大部分和SoftCache一樣
内部成員
private static class WeakEntry extends WeakReference<Object> {
private final Object key;
private WeakEntry(Object key, Object value, ReferenceQueue<Object> garbageCollectionQueue) {
super(value, garbageCollectionQueue);
this.key = key;
}
}