mybatis缓存LruCache源码分析

2024-08-21 02:58

本文主要是介绍mybatis缓存LruCache源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LruCache

  • LruCache是如何实现的
  • linkedHashMap源码分析
    • 双向链表
      • 链表优点
      • 链表缺点
      • 双向链表节点
      • 移动节点到链表的尾部
    • 为什么要散列表和链表搭配使用

LruCache是如何实现的

LruCache的关键代码:

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);}public void setSize(final int size) {/*** 重写方法:是否移除最老的链表节点,最老的链表节点就是链表的头节点*/keyMap = new LinkedHashMap<Object, Object>(size, .75F, true) {private static final long serialVersionUID = 4267176411845948333L;@Overrideprotected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {// 判断什么时候需要移除最老的节点boolean tooBig = size() > size;if (tooBig) {// 保存最老的链表节点的key,方便cycleKeyList()删除相应的keyeldestKey = eldest.getKey();}return tooBig;}};}@Overridepublic Object getObject(Object key) {// 虽然没有使用这个返回值,但是需要更细linkedHashMap的使用情况keyMap.get(key); // touchreturn delegate.getObject(key);}private void cycleKeyList(Object key) {/*** 这个方法会更新eldestKey的值* 此方法在hashMap当中,调用过程:hashmap.put()->linkedHashMap.afterNodeInsertion()->linkedHashMap.removeEldestEntry()* 最终eldestKey的值被更新*/keyMap.put(key, key);// 如果eldestKey的值被更新,则需要到真正存储缓存的地方删除键值对if (eldestKey != null) {delegate.removeObject(eldestKey);eldestKey = null;}}}

linkedHashMap源码分析

双向链表

链表优点

  1. 插入,删除,新增操作的时间复杂度都是O(1)
  2. 可以利用不连续的内存空间

链表缺点

  1. 不能随机查找,随机查找的时间复杂度是o(n)
  2. 因为要保存前后节点的引用,所以占用的内存空间会变大

双向链表节点

/*** 继承了HashMap.Node* 其实就是在hashMap节点的基础上加入before和after节点* 构成了双向链表的节点* @param <K>* @param <V>*/static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after;Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}}

移动节点到链表的尾部

当get()被调用了,当前节点就变成最新被访问的了,需要移动到链表的尾部

void afterNodeAccess(Node<K,V> e) { // move node to lastLinkedHashMap.Entry<K,V> last;/*** 两个判断逻辑:* 1 链表是否支持按照最近最新使用规则排序,默认按照插入顺序排序* 2 当前节点是否已经是尾节点了*/if (accessOrder && (last = tail) != e) {LinkedHashMap.Entry<K,V> p =(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;p.after = null;if (b == null) // 说明当前节点是headhead = a; //重新定义head elseb.after = a; // 重新定义p.before的指向if (a != null) a.before = b; // 重新定义p.after的指向else // a==null说明b已经是尾节点了last = b;if (last == null) // 说明当前链表为空head = p;else {   // 定义新的为节点p.before = last;last.after = p;}// 新的尾节点产生,可以看出移动链表的节点不需要通过遍历链表tail = p;++modCount;}}

为什么要散列表和链表搭配使用

针对链表不能随机访问的缺点,如果使用散列表随机访问时间复杂度为O(1)的有点,两者扬长避短,充分发挥各自的优势

这样一来,可以创建有序的map键值对

public class LinkedHashMap<K,V>extends HashMap<K,V>implements Map<K,V>

这篇关于mybatis缓存LruCache源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1091929

相关文章

MyBatis ResultMap 的基本用法示例详解

《MyBatisResultMap的基本用法示例详解》在MyBatis中,resultMap用于定义数据库查询结果到Java对象属性的映射关系,本文给大家介绍MyBatisResultMap的基本... 目录MyBATis 中的 resultMap1. resultMap 的基本语法2. 简单的 resul

Mybatis的分页实现方式

《Mybatis的分页实现方式》MyBatis的分页实现方式主要有以下几种,每种方式适用于不同的场景,且在性能、灵活性和代码侵入性上有所差异,对Mybatis的分页实现方式感兴趣的朋友一起看看吧... 目录​1. 原生 SQL 分页(物理分页)​​2. RowBounds 分页(逻辑分页)​​3. Page

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Mybatis Plus Join使用方法示例详解

《MybatisPlusJoin使用方法示例详解》:本文主要介绍MybatisPlusJoin使用方法示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录1、pom文件2、yaml配置文件3、分页插件4、示例代码:5、测试代码6、和PageHelper结合6

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

MyBatis设计SQL返回布尔值(Boolean)的常见方法

《MyBatis设计SQL返回布尔值(Boolean)的常见方法》这篇文章主要为大家详细介绍了MyBatis设计SQL返回布尔值(Boolean)的几种常见方法,文中的示例代码讲解详细,感兴趣的小伙伴... 目录方案一:使用COUNT查询存在性(推荐)方案二:条件表达式直接返回布尔方案三:存在性检查(EXI

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb