带你彻底搞懂MyBatis的底层实现之缓存模块(Cache)-吊打面试官必备技能

本文详细介绍了MyBatis的一级缓存PerpetualCache及其装饰器BlockingCache的工作原理,包括加锁和解锁操作。此外,还探讨了其他缓存装饰器如LRU、FIFO和日志功能的实现,并解析了MyBatis配置中的缓存初始化过程。最后,文章强调了一级缓存的生命周期和在SqlSession中的应用。
摘要由CSDN通过智能技术生成

*/

public class PerpetualCache implements Cache {

private final String id; // Cache 对象的唯一标识

// 用于记录缓存的Map对象

private final Map<Object, Object> cache = new HashMap<>();

public PerpetualCache(String id) {

this.id = id;

}

@Override

public String getId() {

return id;

}

@Override

public int getSize() {

return cache.size();

}

@Override

public void putObject(Object key, Object value) {

cache.put(key, value);

}

@Override

public Object getObject(Object key) {

return cache.get(key);

}

@Override

public Object removeObject(Object key) {

return cache.remove(key);

}

@Override

public void clear() {

cache.clear();

}

@Override

public boolean equals(Object o) {

if (getId() == null) {

throw new CacheException(“Cache instances require an ID.”);

}

if (this == o) {

return true;

}

if (!(o instanceof Cache)) {

return false;

}

Cache otherCache = (Cache) o;

// 只关心ID

return getId().equals(otherCache.getId());

}

@Override

public int hashCode() {

if (getId() == null) {

throw new CacheException(“Cache instances require an ID.”);

}

// 只关心ID

return getId().hashCode();

}

}

然后我们可以来看看cache.decorators包下提供的装饰器。他们都实现了Cache接口。这些装饰器都在PerpetualCache的基础上提供了一些额外的功能,通过多个组合实现一些特殊的需求。

3 BlockingCache


通过名称我们能看出来是一个阻塞同步的缓存,它保证只有一个线程到缓存中查找指定的key对应的数据。

public class BlockingCache implements Cache {

private long timeout; // 阻塞超时时长

private final Cache delegate; // 被装饰的底层 Cache 对象

// 每个key 都有对象的 ReentrantLock 对象

private final ConcurrentHashMap<Object, ReentrantLock> locks;

public BlockingCache(Cache delegate) {

// 被装饰的 Cache 对象

this.delegate = delegate;

this.locks = new ConcurrentHashMap<>();

}

@Override

public String getId() {

return delegate.getId();

}

@Override

public int getSize() {

return delegate.getSize();

}

@Override

public void putObject(Object key, Object value) {

try {

// 执行 被装饰的 Cache 中的方法

delegate.putObject(key, value);

} finally {

// 释放锁

releaseLock(key);

}

}

@Override

public Object getObject(Object key) {

acquireLock(key); // 获取锁

Object value = delegate.getObject(key); // 获取缓存数据

if (value != null) { // 有数据就释放掉锁,否则继续持有锁

releaseLock(key);

}

return value;

}

<
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值