Java设计本地缓存

简介: Java设计本地缓存

正文


本地缓存实际上就是将数据存储在自己的应用中,没有存储到其他的位置,例如:Redis等等。本地缓存的一大好处是处理速递极快而且不需要访问下游的数据,但是,它也存在缺点。当一个应用是集群的方式部署的时候,由于本地缓存信息缺乏信息共享的能力,所以,同一个数据会存在多个应用中,有可能造成结果的不一致性。但是,我们也是离不开本地缓存的,我们可以设计成下面这样,可以有效地解决网络延时问题。



40.png


今天给大家介绍的是本地缓存的设计,在这其中,会使用几种设计模式,例如:装饰者模式、单例模式等等。一共分为下面的4大部分:

1. 定义缓存接口,用于阐述缓存的功能。

2. 持久性缓存实现

3. LRU缓存实现

4. 带有版本的缓存实现


第一步:定义缓存接口,用于阐述缓存的功能。


/**
 * 缓存接口
 *
 * @author breakpoint/赵先生
 * create on 2021/02/03
 */
public interface Cache<T> {
    // get ID
    String getId();
    // get SIZE
    int getSize();
    // 放入对象
    void putObject(String key, T value);
    // 获取到对象
    T getObject(String key);
    // 移除对象
    T removeObject(String key);
    // 清除所有的对象
    void clear();
    // 获取所有的缓存
    List<T> getAll();
    // 获取锁的结构
    ReadWriteLock getReadWriteLock();
}


42.png

第二步:持久性缓存实现

持久化缓存实现的方式采用Map实现,同时为了多线程操作的问题,这里使用了读写锁操作数据的读取与更新。


43.png


44.png

45.png

获取读写锁这里(上面的图片),采用的是DCL单例模式。第三步:LRU缓存实现在实现LRU缓存这里,使用了装饰者模式,如下面的delegate对象就是操作的真实对象。并且采用LinkedHashMap记录最近最久未使用的key,然后针对相应的数据进行移除。


46.png47.png


第四步:带有版本时间的缓存实现这个实现带有时间失效的特点,但是如果在有效的时间内访问,就会重新设置这个值的有效时间。

48.png

在定义获取线程池操作时,这里采用的是自定义线程池,并且是单个有节线程池。同时采用内部静态类的方式实现单例模式。如下图:


49.png


在提交,创建缓存对象的时候才会创建线程池的实例,节省资源。


50.png


通过上面的一整个的操作流程,实现了定时的清除过期的数据,防止存在内存泄漏的风险。


51.png

在获取对象的时候,会动态地更新这个数据的有效时间。如上图。

52.png


在清理数据的时候,每清理5000个数据,这里给JVM一次机会进行垃圾回收,如上图。


总结


这个本地缓存的实现参考了Mybatis的本地缓存,并且在此基础上进行了优化,同时添加了带有版本缓存时间的本地缓存。在实现的过程中,使用了装饰者模式和DCL单例模式以及内部静态类单例模式。

相关文章
|
1月前
|
缓存 Java
java开发常用模块——缓存模块
java开发常用模块——缓存模块
|
2月前
|
缓存 Java
【JAVA】基于Guava实现本地缓存
【JAVA】基于Guava实现本地缓存
33 0
|
2月前
|
缓存 算法 Java
Caffeine Cache~高性能 Java 本地缓存之王
Caffeine Cache~高性能 Java 本地缓存之王
82 1
|
2月前
|
缓存 Java
JAVA带缓存的输入输出流
JAVA带缓存的输入输出流
21 0
|
5月前
|
缓存 NoSQL Java
Java项目启动时先加载某些方法可用于redis缓存预热
Java项目启动时先加载某些方法可用于redis缓存预热
67 0
|
5月前
|
存储 缓存 NoSQL
在Java中实现redis缓存中的布隆过滤器
在Java中实现redis缓存中的布隆过滤器
38 0
|
3天前
|
缓存 算法 Java
Java本地高性能缓存实践
本篇博文将首先介绍常见的本地缓存技术,对本地缓存有个大概的了解;其次介绍本地缓存中号称性能最好的Cache,可以探讨看看到底有多好?怎么做到这么好?最后通过几个实战样例,在日常工作中应用高性能的本地缓存。
|
24天前
|
存储 缓存 监控
构建高效的Java缓存策略
【4月更文挑战第18天】本文探讨了如何构建高效的Java缓存策略,强调缓存可提升系统响应和吞吐量。关键因素包括缓存位置、粒度、失效与更新策略、并发管理、序列化及选择合适库(如Ehcache、Guava Cache、Caffeine)。最佳实践包括明确需求、选择合适解决方案、监控调整及避免常见陷阱。缓存优化是一个持续过程,需根据需求变化不断优化。
|
26天前
|
缓存 NoSQL Java
使用Redis进行Java缓存策略设计
【4月更文挑战第16天】在高并发Java应用中,Redis作为缓存中间件提升性能。本文探讨如何使用Redis设计缓存策略。Redis是开源内存数据结构存储系统,支持多种数据结构。Java中常用Redis客户端有Jedis和Lettuce。缓存设计遵循一致性、失效、雪崩、穿透和预热原则。常见缓存模式包括Cache-Aside、Read-Through、Write-Through和Write-Behind。示例展示了使用Jedis实现Cache-Aside模式。优化策略包括分布式锁、缓存预热、随机过期时间、限流和降级,以应对缓存挑战。
|
28天前
|
存储 缓存 Java
java如何实现一个LRU(最近最少使用)缓存?
实现了一个LRU缓存,使用双向链表保持访问顺序,哈希表用于定位元素。Java代码中,`LRUCache`类包含容量、哈希表及链表头尾节点。`get`方法查哈希表,找到则移动至链表头并返回值,否则返回-1。`put`方法更新或插入节点,超出容量则移除最不常用节点。
16 6