天天看點

Mybatis的這兩個緩存裝飾器不要忽略

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);
    }
  }
           
  1. 調用removeGarbageCollectedItems()方法,這個方法是周遊queueOfGarbageCollectedEntries記錄的被垃圾回收器回收value對象對應的key,然後從被裝飾器中删除緩存
  2. 調用被裝飾器放入緩存

擷取元素

從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;
  }
           
  1. 軟引用中記錄了這個key,對應value軟引用中沒有了就調用被裝飾器删除對應的緩存
  2. 把用到的value值放入LinkedList頭部中,這樣value就是強引用了,不會被垃圾回收器回收,預設放入256個,超出就删除尾部的
  3. 傳回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;
    }
  }
           

總結

繼續閱讀