• 首页

  • 归档
小 黑 捡 方 块
小 黑 捡 方 块

小黑捡方块

获取中...

05
08
mybatis

Mybatis的LruCache是怎样实现的

发表于 2020-05-08 • 被 330 人看爆

LRU是什么

  • 定义

注释中有解释LRU算法是什么Lru (least recently used) cache decorator即:最近最少使用

  • 核心思想

如果数据最近被访问过,那么将来被访问的几率也更高,同理:如果数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小

Mybatis的LruCache是怎样实现的

  • 分析源码

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;

import org.apache.ibatis.cache.Cache;

/**
 * Lru (least recently used) cache decorator
 *
 * @author Clinton Begin
 */
public class LruCache implements Cache {

  private final Cache delegate;
  private Map<Object, Object> keyMap;
  private Object eldestKey;

  public LruCache(Cache delegate) {
    this.delegate = delegate;
    setSize(1024);
  }

  @Override
  public String getId() {
    return delegate.getId();
  }

  @Override
  public int getSize() {
    return delegate.getSize();
  }

  /**
   * 设置缓存大小
   * 可以看到这里有初始化key的缓存
   * 而对缓存的淘汰算法完全可以是对key的淘汰算法,也就是说这里就是我们要找的地方了
   * 
   * @param size
   */
  public void setSize(final int size) {
    keyMap = new LinkedHashMap<Object, Object>(size, .75F, true) {
      private static final long serialVersionUID = 4267176411845948333L;

      @Override
      protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
        boolean tooBig = size() > size;
        if (tooBig) {
          eldestKey = eldest.getKey();
        }
        return tooBig;
      }
    };
  }

  /**
   * 往缓存里放对象,不看
   * @param key
   * @param value
   */
  @Override
  public void putObject(Object key, Object value) {
    delegate.putObject(key, value);
    cycleKeyList(key);
  }

  @Override
  public Object getObject(Object key) {
    keyMap.get(key); //touch
    return delegate.getObject(key);
  }

  /**
   * 从缓存中移除对象,不看
   * @param key
   * @return
   */
  @Override
  public Object removeObject(Object key) {
    return delegate.removeObject(key);
  }

  /**
   * 清空缓存和key缓存,不看
   */
  @Override
  public void clear() {
    delegate.clear();
    keyMap.clear();
  }

  /**
   * 获取读写锁,不看
   * @return
   */
  @Override
  public ReadWriteLock getReadWriteLock() {
    return null;
  }

  /**
   * 循环Key列表,不看
   * @param key
   */
  private void cycleKeyList(Object key) {
    keyMap.put(key, key);
    if (eldestKey != null) {
      delegate.removeObject(eldestKey);
      eldestKey = null;
    }
  }

}

Java

Copy

  • 原理分析

  1. 通过以上的源码分析可以看到setSize()方法才是我们需要关注的地方
  2. keyMap是一个LinkedHashMap,并且对LinkedHashMap的排序规则(accessOrder)进行了设置
  3. 看LinkedHashMap源码注释:the ordering mode - {@code true} for
    access-order, {@code false} for insertion-order,就是说true是按照访问顺序排序,false是按照插入顺序排序。
  4. 那么究竟是什么意思,可以查看stackoverflow,就是说LinkedHashMap本身已经帮我们实现了LRU算法,LinkedHashMap把最近访问的key放到了链表最后面
  5. 所以最终mybatis的LruCache是LinkedHashMap实现的,我们只需要研究LinkedHashMap的LRU算法即可
分享到:
今天发现数据库被搞了
安卓项目导入后不识别
  • 文章目录
  • 站点概览
小黑捡方块

帅哥小黑捡方块

Github Email RSS
看爆 Top5
  • jenkins通过ssh连接失败:Failed to add SSH key. Message [invalid privatekey 1,211次看爆
  • ConcurrentHashMap核心部分源码注释 1,168次看爆
  • docker运行的jenkins在构建项目并打包成docker镜像时问题总结 1,124次看爆
  • docker启动后外网和主机死活访问不到springboot项目 661次看爆
  • Springboot+Nginx+certbot重定向400错误解决 607次看爆
蜀ICP备19040029号

Copyright © 2021 小黑捡方块 ·

Proudly published with Halo · Theme by fyang · 站点地图