【设计一个缓存--针对各种类型的缓存】

设计一个缓存--针对各种类型的缓存

  • 1. 设计顶层接口
  • 2. 设计抽象类 -- AbstractCacheManager
  • 3. 具体子类
    • 3.1 -- AlertRuleItemExpCacheManager
    • 3.2 -- AlertRuleItemSrcCacheManager
  • 4. 类图关系

1. 设计顶层接口

// 定义为一个泛型接口,提供给抽象类使用
public interface CacheManager<T> {// 获取所有的缓存itemList<T> getAll();// 根据条件获取某些缓存itemList<T> get(Predicate<T> predicate);// 设置缓存boolean set(T t);// 设置缓存listboolean set(List<T> tList);
}

有接口必定有实现类或者抽象类,实现接口。
那为了更好地控制子类的行为,可以做一个抽象类,控制子类行为。

  • 分析:
    • 抽象类作为缓存管理的话,那么就需要提供安全访问数据
    • 需要考虑线程安全问题。
    • 花絮: 不仅要满足上述需求,而且让代码尽量简洁。

2. 设计抽象类 – AbstractCacheManager

  • 属性设计:
    • 需要一个缓存
    • 需要一个线程安全机制方案
  • 行为设计:
    • 自己的行为:
      • 利用线程安全机制控制缓存的读写。
      • 权限:仅自己可访问
    • 后代的行为:
      • 访问一些简单api方法即可实现安全访问缓存
      • 权限:公共访问
  • 设计模式:
    • 包裹思想,将后代行为方法中,包裹一层安全访问的行为。

Java Code:

 // properties design:
protected ConcurrentMap<String, T> cache;private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();// subclass to implements these abstract methods.protected abstract List<T> getAllByCache();protected abstract void setByCache(T t);protected abstract void setByCache(List<T> tList);protected abstract List<T> getByCache(Predicate<T> predicate);// next content needs to consider safety of multithreads. following methods do implements.
// entry to use
@Override
public final List<T> getAll() {return this.readLockThenGet(() -> this.getAllByCache());
}@Override
public final List<T> get(Predicate<T> predicate) {return this.readLockThenGet(pre -> getByCache(pre), predicate);
}@Override
public final boolean set(T t) {return this.writeLockThenSet((Consumer<T>) obj -> set(obj), t);
}@Override
public final boolean set(List<T> tList) {return this.writeLockThenSet((Consumer<List<T>>) list -> set(list), tList);
}// current abstract class access cache object.
private boolean writeLockThenSet(Consumer consumer, Object object){boolean wLock = false;try {if (!(wLock = lock.writeLock().tryLock(100, TimeUnit.MICROSECONDS))) {return false;}consumer.accept(object);return true;} catch (Exception e) {return false;} finally {if(wLock) {lock.writeLock().unlock();}}
}private List<T> readLockThenGet(Supplier<List<T>> supplier){boolean rLock = false;try{if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){return null;}return supplier.get();}catch (Exception e){return null;}finally {if(rLock) {lock.readLock().unlock();}}
}private List<T> readLockThenGet(Function<Predicate<T>, List<T>> function, Predicate<T> predicate){boolean rLock = false;try{if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){return null;}return function.apply(predicate);}catch (Exception e){return null;}finally {if(rLock) {lock.readLock().unlock();}}
}

3. 具体子类

3.1 – AlertRuleItemExpCacheManager

@Component("alertRuleItemExpCacheManager")
public class AlertRuleItemExpCacheManager<T extends AlertRuleItemExpCache> extends AbstractCacheManager<AlertRuleItemExpCache> {@Resourceprivate AlertRuleItemExpDao alertRuleItemExpDao;@Overrideprotected List<AlertRuleItemExpCache> getAllByCache() {if (null == cache) {List<AlertRuleItemExp> alertRuleItemSrcList =alertRuleItemExpDao.selectList(Wrappers.<AlertRuleItemExp>lambdaQuery().eq(AlertRuleItemExp::getDeleted, 0));cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache()).collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));}return cache.values().stream().sorted(Comparator.comparing(AlertRuleItemExpCache::getId)).collect(Collectors.toList());}@Overrideprotected void setByCache(AlertRuleItemExpCache alertRuleItemExpCache) {cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache);}@Overrideprotected void setByCache(List<AlertRuleItemExpCache> alertRuleItemExpCacheList) {alertRuleItemExpCacheList.parallelStream().forEach(alertRuleItemExpCache ->cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache));}@Overrideprotected List<AlertRuleItemExpCache> getByCache(Predicate<AlertRuleItemExpCache> predicate) {return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());}
}

3.2 – AlertRuleItemSrcCacheManager

@Component("alertRuleItemSrcCacheManager")
public class AlertRuleItemSrcCacheManager<T extends AlertRuleItemSrcCache> extends AbstractCacheManager<AlertRuleItemSrcCache> {@Resourceprivate AlertRuleItemSrcDao alertRuleItemSrcDao;@Overrideprotected List<AlertRuleItemSrcCache> getAllByCache() {if (null == cache) {List<AlertRuleItemSrc> alertRuleItemSrcList =alertRuleItemSrcDao.selectList(Wrappers.<AlertRuleItemSrc>lambdaQuery().eq(AlertRuleItemSrc::getDeleted, 0));cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache()).collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));}return cache.values().stream().sorted(Comparator.comparing(AlertRuleItemSrcCache::getId)).collect(Collectors.toList());}@Overrideprotected void setByCache(AlertRuleItemSrcCache alertRuleItemSrcCache) {cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache);}@Overrideprotected void setByCache(List<AlertRuleItemSrcCache> alertRuleItemSrcCacheList) {alertRuleItemSrcCacheList.parallelStream().forEach(alertRuleItemSrcCache ->cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache));}@Overrideprotected List<AlertRuleItemSrcCache> getByCache(Predicate<AlertRuleItemSrcCache> predicate) {return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());}
}

4. 类图关系

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/145775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

02-2解析JsonPath

一、jsonpath的安装及使用方式 pip安装 pip install jsonpathjsonpath的使用 obj json.load(open(json文件, r, encodingutf‐8)) ret jsonpath.jsonpath(obj, jsonpath语法)可以参考以下这篇博客进行jsonpath的简单入门JSONPath-简单入门

Centos7安装Redis

1.背景 2.步骤 1.安装gcc依赖 检查是否已安装gcc gcc -v 上图表示已安装,如果没有安装执行如下命令 [rootlocalhost local]# yum install -y gcc 2.下载并解压安装包 [rootlocalhost local]# wget http://download.redis.io/releases/redis-5.0.3.tar.gz [rootlocalhost lo…

《011.SpringBoot之餐厅点餐系统》

《011.SpringBoot之餐厅点餐系统》【界面简洁功能简单】 项目简介 需要源码及数据库的私信… [1]本系统涉及到的技术主要如下&#xff1a; 推荐环境配置&#xff1a;DEA jdk1.8 Maven MySQL 前后端分离; 后台&#xff1a;SpringBootMybatisPlus; 前台&#xff1a;Layuivue; …

SHELL中case的使用

快捷查看指令 ctrlf 进行搜索会直接定位到需要的知识点和命令讲解&#xff08;如有不正确的地方欢迎各位小伙伴在评论区提意见&#xff0c;博主会及时修改&#xff09; shell中的case语句 在shell脚本中&#xff0c;case语句用于匹配一个变量的值。它类似于if语句&#xff0c;…

【python】OpenCV—Image Pyramid(8)

文章目录 1 图像金字塔2 拉普拉斯金字塔 1 图像金字塔 高斯金字塔 在 OpenCV 中使用函数 cv2.pyrDown()&#xff0c;实现图像高斯金字塔操作中的向下采样&#xff0c;使用函数 cv2.pyrUp() 实现图像金字塔操作中的向上采样 import cv2img cv2.imread(C://Users/Administrat…

Mysql中的进阶增删查改操作(二)

联合查询和合并查询 一.联合查询1.内连接2.外链接2.1左外连接2.2右外连接 3.自连接4.子查询5.合并查询 一.联合查询 步骤 1.进行笛卡尔积 2.列出连接条件 3.根据需求再列出其他条件 4.针对列进行精简(可以使用聚合函数) 我们先搭建一个多表查询的框架 这样一个多表查询就搭建出…

基于JAVA SpringBoot和HTML美食网站博客程序设计

摘要 美食网站是一个提供各种美食信息和食谱的网站&#xff0c;旨在帮助用户发现、学习和分享美食。旨在探讨美食网站在现代社会中的重要性和影响。随着互联网的普及&#xff0c;越来越多的人开始使用美食网站来获取各种美食信息和食谱。这些网站不仅提供了方便快捷的搜索功能&…

MySQL8.0学习笔记

1. CMD命令 1.1 数据库启动与停止 (1) 启动数据库&#xff1a;net start mysql80 (2) 停止数据库&#xff1a;net stop mysql80 1.2 数据库连接与退出 (1) 连接数据库&#xff1a;mysql [-hlocalhost -P3306] -uroot -p[123456] // 本地数据库可省略-h -P (2) 退出数据库…

在市场发展中寻变革,马上消费金融树行业发展“风向标”

11月11日&#xff0c;2023金融街论坛年会第三届全球金融科技大会“金融科技创新与合规安全”平行论坛在北京召开。会上&#xff0c;马上消费金融副总经理孙磊就数据对金融的赋能作用、数据安全治理等方面展开了深度讨论。 公开信息显示&#xff0c;马上消费金融是一家经中国银保…

CodeWhisperer--手把手教你使用一个十分强大的工具

Amazon CodeWhisperer 是一款能够帮助我们智能生成代码的工具。经过数十亿行代码的训练&#xff0c;可以根据提示和现有代码实时生成从片段到完整功能的代码建议。类似 Cursor 和 Github Copilot 编码工具。目前&#xff0c;CodeWhisperer 兼容 Python、Java 和 JavaScript&…

Vue 路由props 多路由参数时使用

传统路由参数获取 this.$route.query.id this.$route.query.a this.$route.query.b this.$route.query.c this.$route.query.d this.$route.query.e ......如果参数很多&#xff0c;特别麻烦 第一种接收parpas参数 使用props http.www.csdn.net/123/321 {name: user,path: /us…

mysql数据模型

创建数据库 命令 create database hellox &#xff1a; &#xff08; hellox名字&#xff09; sql语句 创建 数据库 命令 create database hell&#xff1b; 也是创建但是有数据库不创建 命令 create database if not exists hell ; 切换数据库 命令 use hello&…

MacBook 常用快捷键使用

MacBook 常用快捷键使用 官方使用地址: https://support.apple.com/zh-cn/HT201236 commandn 新建 如果QQ要开多个&#xff0c;可以打开QQ后按commandn 又打开一个了 终端 commandn重新打开一个&#xff0c;commandt在当前终端在打个一个选项卡commandw 关闭最前面的窗口…

2023解析企业数据中台:突破数据孤岛,实现数据化管理升级-亿发

当前&#xff0c;各大企业纷纷将业务中台、数据中台、安全中台等纳入建设计划&#xff0c;其中&#xff0c;数据中台被视为重中之重。但是&#xff0c;对于初接触者而言&#xff0c;对数据中台的定义可能存在一些模糊。 下面我们将讨论和讲解对企业建设数据中台的3点建议&#…

小型机房380V断电报警门磁开关状态检测远程控制RTU

在现代社会中&#xff0c;小型机房起到了至关重要的作用&#xff0c;为各种系统和设备提供稳定的电力供应。然而&#xff0c;由于各种原因&#xff0c;如供电故障、设备故障或非法侵入等&#xff0c;机房的正常运行可能会受到威胁。为了保障机房的安全和可靠性&#xff0c;我们…

使用WildCard充值ChatGPT Plus 会员

登录 wildCard官网 基于国内手机号注册账号&#xff0c;使用支付宝验证付款即可自动申请国外银行卡&#xff0c;WildCard的开卡费是9.9美元, 没有后续的月费用.订阅chatgpt plus会员服务的操作图文指南见链接 chatgpt plus会员订阅指南

ROS 通信机制

ROS是一个分布式框架&#xff0c;为用户提供多节点&#xff08;进程&#xff09;之间的通信服务&#xff0c;所有软件和功能都建立在这种分布式通信机制上&#xff0c;ROS的通信机制是最底层也是最核心的技术。 一、话题通信机制 话题在 ROS 中使用最为频繁&#xff0c;其通信…

基于JavaWeb+SpringBoot+Vue房屋租赁系统微信小程序系统的设计和实现

基于JavaWebSpringBootVue房屋租赁系统微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 21世纪是信息的时代&#xff0c;是网络的时代&#xff0c;进入信息社会高速…

[Python学习笔记]Requests性能优化之Session

Requests 可是说是 Python 中最常用的库了。用法也非常简单&#xff0c;但是想真正的用的好并不容易。 下面介绍一个提升性能小技巧&#xff1a;使用 session 会话功能。 以下是 Requests 官网的介绍&#xff1a; 会话对象让你能够跨请求保持某些参数。它也会在同一个 Sessio…