Mybatis源码-Cache包的内容

本文深入探讨MyBatis缓存装饰器的工作原理,包括BlockingCache、FifoCache、LruCache等在内的十种装饰器,以及它们如何丰富核心缓存PerpetualCache的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天看完mybatis所有缓存装饰类,总结整理一下

1、BlockingCache

上篇已经说了,BlockingCache 它特点就是不同缓存key会阻塞,如果一个线程没有获取某个key对应value,它就不会释放锁,它锁采用是ReentrantLock(重入锁),同一个线程可以加锁多次,但是也必须解锁相同的次数,其他线程才可访问该key,进行加锁。

2、FifoCache(先进先出缓存装饰类)

  1. 它的实现是通过LinkedList双队列方式存入缓存的key,一端放入最新缓存的key,如果超过阈值,就在另一端移除缓存key
  2. 默认大小队列的大小是1024

3、LoggingCache(日志缓存装饰类)

  1. 设计主要目的是在debug模式调试某个缓存的命中率,也就是
  2. 命中率=获取到值次数/请求次数

4、LruCache(最近最少使用缓存装饰类)

  1. 设计思路就是用进废退思想,经常用会放在前面不会被清除掉(通过put或get方法获取某个缓存key对象,那么这个缓存key自动排在最前面)
  2. 默认的大小也是1024
  3. 它是采用LinkedHashMap实现的,重写removeEldestEntry的方法,判断当前缓存key的个数是否超过阈值,如果超过了,就获取到最不经常用的key,在下一次put的时候,进行移除该key的缓存对象
    测试代码
/**
   * 默认大小是1024, 会清除索引为0数据
   * 最新操作的元素总是放在最后位置, 从前面删除元素
   * @param args
   */
  public static void main(String[] args) {
    LruCache lruCache = new LruCache(new PerpetualCache("com.jack.pa"));
    lruCache.setSize(3);
    lruCache.putObject(1, 1);
    lruCache.putObject(2, 2);
    lruCache.putObject(3, 3); // 123
    lruCache.putObject(4, 4); // 234
    lruCache.getObject(3); // 243
    for (Map.Entry<Object, Object> entry : lruCache.keyMap.entrySet()) {
      System.out.println("key:"+ entry.getKey() + " value:" + entry.getValue());
    }

  }

5、ScheduledCache(定间隔清理缓存装饰类)

  1. 第一它并没有定时任务去清除缓存,只是调用这个方法才会真正的清除
  2. 默认缓存清除时间是1小时
/**
   * 立即获取:1
     延迟2秒获取:null
   * @param args
   * @throws InterruptedException
   */
  public static void main(String[] args) throws InterruptedException {
    ScheduledCache scheduledCache = new ScheduledCache(new PerpetualCache("com.jack.pa"));
    scheduledCache.setClearInterval(1000);
    scheduledCache.putObject(1,1);
    System.out.println("立即获取:" + scheduledCache.getObject(1));
    Thread.sleep(2000);
    System.out.println("延迟2秒获取:" + scheduledCache.getObject(1));

  }

6、SerializedCache(序列化缓存装饰类)

  1. 本质就是把对象以byte[] 数组存入缓存对象中
  2. 缓存对象必须要实现serializable接口
  3. 自定义ObjectInputStream 重写resolveClass方法, 使用自己Resource获取Class类

  /**
   * 把缓存的对象采用byte[]数组进行存储
   * @param args
   */
  public static void main(String[] args) {
    LruCache serializedCache = new LruCache(new SerializedCache(new PerpetualCache("com.jack.pa")));
    serializedCache.putObject("1121211","21132131312");
    serializedCache.getObject("1121211");

  }

7、SoftCache(软引用缓存装饰类)

  1. 一般用于内存比较敏感,当内存不够的时候,GC可以进清除这些缓存
  2. 里面有两个成员变量一个是避免GC回收集合(hardLinksToAvoidGarbageCollection),默认大小是256,一个关联GC收集(queueOfGarbageCollectedEntries)之后,将回收对象存入到ReferenceQueue中来标记该对象已经被回收,缓存真正去移除这个缓存对象
  3. hardLinksToAvoidGarbageCollection集合进行操作的是采用同步操作

8、WeakCache(弱引用缓存装饰类)

1.这个实现类似SoftCache,它比SoftCache更容易被GC回收

9、SynchronizedCache(同步缓存装饰类)

  1. 这个主要是在方法上加了synchronized关键来实现同步操作

10、TransactionCache(事务缓存装饰类)

  1. 这个是一个二级缓存事务的buffer
  2. put操作不会直接put到底层缓存对象中,而是put本对象中entriesToAddOnCommit
  3. 只有在commit操作之后才会将entriesToAddOnCommit刷新到底层缓存对象中
  4. 这个类支持BlockingCache,但是好像有bug
  5. entriesMissedInCache这个集合是存在没有获取到值的缓存key集合(Set集合)
 /**
   * 他说这个类支持BlockingCache,但是发现多次请求同一个key,导致多次加锁,但是这个entriesMissedInCache是Set集合
   * 导致多次加锁之后还是存在一个对象,在解锁的时候只能解锁一次导致其他其他线程不能获取缓存key,所以认为这里可能有bug,把Set缓存List不会出现
   * @param args
   * @throws InterruptedException
   */
  public static void main(String[] args) throws InterruptedException {
    BlockingCache blockingCache = new BlockingCache(new PerpetualCache("com.jack.pa"));
    TransactionalCache transactionalCache = new TransactionalCache(blockingCache);
    for(int i=0 ; i < 10; i++) {
      transactionalCache.getObject(1);
    }
    transactionalCache.rollback();
    Thread tryLock = new Thread(()->{
      transactionalCache.getObject(1);
    });
    tryLock.start();
    tryLock.join();

  }

11、总结

  1. 除了PerpetualCache是真正缓存对象,也就是底层缓存对象,以上10种都是装饰类,丰富PerpetualCache功能,实现它的新特性。
  2. 装饰类的主要操作对象是缓存key,通过缓存key实现一些功能
  3. PerpetualCache底层是HashMap进行存储缓存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值