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

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

  • 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.rhkb.cn/news/198523.html

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

相关文章

数据资产入表,给企业带来的机遇和挑战

作为推动数字经济发展的核心要素&#xff0c;近年来&#xff0c;数据资源对于企业特别是相关数据企业的价值和作用正日益凸显。 数据资产入表之后&#xff0c;能够为企业经营带来实质性的收益。“随着数据资产的纳入&#xff0c;企业的资产也出现了新标的。在资产负债表中&…

【2023春李宏毅机器学习】快速了解机器学习基本原理

文章目录 机器学习约等于机器自动找一个函数 机器学习分类 regression&#xff1a;输出为连续值classification&#xff1a;输出为一个类别structured learning&#xff1a;又叫生成式学习generative learning 生成有结构的物件&#xff08;如&#xff1a;影像、句子&#xf…

ajax异步传值以及后端接收参数的几种方式

异步传值 第一种呢&#xff0c;也是最简单的一种&#xff0c;通过get提交方式&#xff0c;将参数在链接中以问号的形式进行传递 // 前台传值方法 // 触发该方法调用ajaxfunction testAjax(yourData) {$.ajax({type: "get", // 以get方式发起请求url: "/yo…

IC卡操作软件支持PN532

IC卡操作软件&#xff0c;在知道卡片密码的情况下&#xff0c;可以对卡片修改数据&#xff0c;格式化清卡&#xff0c;修改UID卡和CUID卡的卡号&#xff0c;锁UFUID卡等 卡片dump文件拖进软件&#xff0c;即可打开文件&#xff0c;编辑修改文件&#xff0c;写卡&#xff0c;就…

upload-labs关卡11(双写后缀名绕过)通关思路

文章目录 前言一、回顾前几关知识点二、靶场第十一关通关思路1、看源代码2、bp抓包双写后缀名绕过3、检查文件是否成功上传 总结 前言 此文章只用于学习和反思巩固文件上传漏洞知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去尚未授权的…

将Agent技术的灵活性引入RPA,清华等发布自动化智能体ProAgent

近日&#xff0c;来自清华大学的研究人员联合面壁智能、中国人民大学、MIT、CMU 等机构共同发布了新一代流程自动化范式 “智能体流程自动化” Agentic Process Automation&#xff08;APA&#xff09;&#xff0c;结合大模型智能体帮助人类进行工作流构建&#xff0c;并让智能…

Neo4j数据库介绍及简单使用

图数据库介绍 图数据库是一种专门设计用于存储和管理图形数据的数据库类型。在图数据库中&#xff0c;数据以图的形式表示&#xff0c;其中节点表示实体&#xff0c;边表示实体之间的关系。这种表示方式非常适合处理具有复杂关系的数据&#xff0c;如社交网络、推荐系统、网络…

代码随想录算法训练营第五十九天丨 单调栈02

503.下一个更大元素II 思路 做本题之前建议先做739. 每日温度 (opens new window)和 496.下一个更大元素 I (opens new window)。 这道题和739. 每日温度 (opens new window)也几乎如出一辙。 不过&#xff0c;本题要循环数组了。 关于单调栈的讲解我在题解739. 每日温度 …

数据结构 栈与队列详解!!

一.栈 关于内存中的栈和数据结构中的栈是不同的&#xff0c;本章着重讲的是数据结构的栈。 这是一张关于栈的表达图。从图中可以看出栈很像是一副卡牌&#xff0c;发牌时只能从上取出&#xff0c;即出栈。 而入栈则是像你出牌后&#xff0c;要把你出的牌压在上一张出的牌上面。…

asp.net校园二手交易平台系统VS开发sqlserver数据库web结构c#编程计算机网页

一、源码特点 asp.net校园二手交易平台系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 vs2010&#xff0c;数据库为sqlserver2008&a…

pytorch单精度、半精度、混合精度、单卡、多卡(DP / DDP)、FSDP、DeepSpeed模型训练

pytorch单精度、半精度、混合精度、单卡、多卡&#xff08;DP / DDP&#xff09;、FSDP、DeepSpeed&#xff08;环境没搞起来&#xff09;模型训练代码&#xff0c;并对比不同方法的训练速度以及GPU内存的使用 代码&#xff1a;pytorch_model_train FairScale&#xff08;你真…

[工业自动化-22]:西门子S7-15xxx编程 - 软件编程 - 如何PLC建立用户界面: SIMATIC 面板式HMI 或工控机PC HMI

目录 前言&#xff1a; 一、PLC&#xff08;可编程逻辑控制器&#xff09;的用户界面支持方式 1.1 概述 1.2 西门子&#xff08;Siemens&#xff09;的人机界面&#xff08;HMI&#xff09;支持多种类型 1.3 PC HMI VS SIMATIC HMI 二、PC—HMI—PLC连接架构的实现 三、…

Go——一、Go语言安装及介绍

Go 一、Windows下安装Go1、下载Go2、配置环境变量3、下载Jetbrain下的GoLang4、编写hello world5、编译和执行 二、Go语言介绍1、开发文档2、Go语言核心开发团队3、为什么要创建Go4、Go语言发展史5、Go语言特点6、Golang执行过程6.1 执行过程分析6.2 编译是什么 7、开发注意事项…

WinForms C# 导入和导出 CSV 文件 Spread.NET

使用 WinForms C# 和 VB.NET 导入和导出 CSV 文件 2023 年 11 月 17 日 使用 Spread.NET 直接在 .NET WinForms 应用程序中处理 CSV 文件。 Spread.NET可帮助您创建电子表格、网格、仪表板和表单。它包括一个强大的计算引擎&#xff0c;具有 450 多个函数以及导入和导出 Micros…

【OpenCV】仿射变换中cv2.estimateAffine2D 的原理

目录 一、介绍 二、仿射变换矩阵 (M) 1.M中六个元素的说明 2.计算旋转角度 3.M的计算过程 三、输出状态 (inliers) 四、错切参数 一、介绍 cv2.estimateAffine2D 是 OpenCV 库中的一个函数&#xff0c;用于估计两个二维点集之间的仿射变换矩阵。即第一个点集经仿射变换转…

解决Requests中使用httpbin服务器问题:自定义URL的实现与验证

问题背景 在使用Python的Requests模块进行单元测试时&#xff0c;可能会遇到无法使用本地运行的httpbin服务器进行测试的问题。这是因为测试脚本允许通过环境变量HTTPBIN_URL指定用于测试的本地httpbin实例&#xff0c;但在某些测试用例中&#xff0c;URL是硬编码为httpbin.or…

成都瀚网科技有限公司抖音带货可靠么

近年来&#xff0c;随着抖音等短视频平台的兴起&#xff0c;越来越多的企业开始利用这些平台进行产品推广和销售。成都瀚网科技有限公司也紧跟这一趋势&#xff0c;通过抖音开展带货业务。那么&#xff0c;成都瀚网科技有限公司的抖音带货是否可靠呢&#xff1f;本文将对此进行…

KylinOSv10修改ulimit值

问题 ulimit 值过小&#xff0c;可能导致压力测试遇到瓶颈&#xff0c;比如通过nginx建立tcp长链接时&#xff0c;链接数量受限。需要修改ulimit值&#xff0c;Linux默认为1024。 解决 使用root或sudo权限&#xff0c;编辑文件/etc/security/limits.conf&#xff0c;新增以下…

pipeline + node +jenkins+kubernetes部署yarn前端项目

1、编写Dockerfile文件 # Set the base image FROM node:16.10.0# WORKDIR /usr/src/app/ WORKDIR /home/option# Copy files COPY ./ /home/option/# Build arguments LABEL branch${BRANCH} LABEL commit${COMMIT} LABEL date${BUILD_DATE} ARG ENV# Set ENV variables ENV …

基于C++实现循环赛日程表(分治算法)

一、问题描叙 设有n2^k个运动员&#xff0c;要进行网球循环赛。现在要设计一个满足以下要求的比赛日程表 每个选手必须与其他n-1个选手各赛一场每个选手一天只能赛一次循环赛一共进行n-1天 二、问题分析 按此要求可将比赛日程表设计成n行n-1列的表&#xff0c;在表中第 i 行…