【设计一个缓存--针对各种类型的缓存】
设计一个缓存--针对各种类型的缓存
- 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. 类图关系

相关文章:
【设计一个缓存--针对各种类型的缓存】
设计一个缓存--针对各种类型的缓存 1. 设计顶层接口2. 设计抽象类 -- AbstractCacheManager3. 具体子类3.1 -- AlertRuleItemExpCacheManager3.2 -- AlertRuleItemSrcCacheManager 4. 类图关系 1. 设计顶层接口 // 定义为一个泛型接口,提供给抽象类使用 public interface Cach…...
Django部署时静态文件配置的坑
Django部署时静态文件配置配置的坑 近期有个需求是用django进行开发部署,结果发现静态文件配置的坑是真的多,另外网上很多的内容也讲不清楚原理,就是这样这样,又那样那样,进了不少坑,这里记录一下关于css,…...
Android---网络编程优化
网络请求操作是一个 App 的重要组成部分,程序大多数问题都是和网络请求有关。使用 OkHttp 框架后,可以通过 EventListener 来查看一次网络请求的详细情况。一次完整的网络请求会包含以下几个步骤。 也就是说,一次网络请求的操作是从 DNS 解析…...
《算法通关村——不简单的字符串转换问题》
《算法通关村——不简单的字符串转换问题》 8. 字符串转换整数 (atoi) 请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C 中的 atoi 函数)。 函数 myAtoi(string s) 的算法如下: 读入…...
给VSCode插上一双AI的翅膀
#AI编程助手哪家好?DevChat“真”好用# 文章目录 前言一、安装DevChat1.1、访问地址1.2、注册1.3、在VSCode里安装DevChat插件1.3.1、未安装状态1.3.2、已安装状态 二、设置Access Key2.1. 点击左下角管理(“齿轮”图标)—命令面板ÿ…...
2023年亚太杯数学建模思路 - 案例:异常检测
文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...
机器学习的医疗乳腺癌数据的乳腺癌疾病预测
项目视频讲解:基于机器学习的医疗乳腺癌数据的乳腺癌疾病预测 完整代码数据分享_哔哩哔哩_bilibili 效果演示: 代码: #第一步!导入我们需要的工具 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns %matplotlib inlin…...
解析:什么是生成式AI?与其他类型的AI有何不同?
原创 | 文 BFT机器人 快速浏览一下头条新闻,你会发现生成式AI似乎无处不在。事实上,一些新闻标题甚至可能是通过生成式AI编写的,例如OpenAI旗下的ChatGPT,这个聊天机器人已经展现出了生成看起来像人类所写文本的惊人能力。 当人们…...
国产化项目改造:使用达梦数据库和东方通组件部署,前后端分离框架
前提:前后端分离前后端包都要用war包。 1、springboot后端改变war包 pom文件添加 <packaging>war</packaging>添加依赖,并且支持tomcat<!-- war包 --><dependency><groupId>org.springframework.boot</groupId><…...
Nginx实现负载均衡
Nginx实现负载均衡 负载均衡的作用 1、解决单点故障,让web服务器构成一个集群 2、将请求平均下发给后端的web服务器 负载均衡的软硬件介绍 负载均衡软件: # nginx 四层负载均衡:stream(nginx 1.9版本以后有stream模块&#x…...
SpringCloud 2022有哪些变化
目录 前提条件 AOT支持 Spring Native支持 前提条件 Spring Cloud 2022.0.0是构建在Spring Framework 6.0和Spring Boot 3.0 之上的一S个主要版本。 JDK要求最低需要是Java 17J2EE要求最低需要Jakarta EE 9 AOT支持 Spring cloud 2022支持AOT编译,它是将程序源…...
如何快速本地搭建悟空CRM结合内网穿透工具高效远程办公
🌈个人主页:聆风吟 🔥系列专栏:数据结构、Cpolar杂谈 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 无需公网IP,使用cpolar实现悟空CRM远程访问二. 通过公网来访问公司…...
Docker打包Python项目
1. 简介 Docker是一种开源的容器化平台,可以将应用程序及其依赖项打包到一个轻量级、可移植的容器中。通过使用Docker,可以简化Python项目的部署和运行,提高开发效率和应用程序的可移植性。 本文将介绍如何使用Docker来打包Python项目。我们…...
【Java并发编程一】并发与并行
为什么引入并发 摩尔定理逐渐失效,单核性能很难提升,通过组合多核性能来进一步满足实际需要,从而引入并发编程。在大部分场景下,并行是由于串行的,并行可以优化非关键节点的时间消耗。 并发的三大特性 原子性 某个…...
MFC/QT 一些快忘记的细节:
1:企业应用中,MFC平台除了用常见的对话框模式还有一种常用的就是单文档模式, 维护别人的代码,不容易区分,看它与程预序认同名cpp,就知道了,比如项目名称为 DoCMFCDemo,那么就看BOOL CDocMFCDe…...
在服务器上部署MVC 6应用程序
在服务器上成功部署MVC 6应用程序(现在更为称为ASP.NET Core MVC)涉及一系列步骤。以下是一般的指导步骤: 1. 准备服务器环境: - 确保服务器上安装了.NET Core Runtime和.NET Core SDK。可以从[.NET下载页面](https://dotnet.mi…...
golang学习笔记——斐波纳契数列
斐波纳契数列 编写一个程序来计算某个数字的斐波纳契数列。 斐波那契数列是一个数字列表,其中每个数字是前两个斐波那契数字之和。 例如,数字 6 的序列是 1,1,2,3,5,8,数字 7 的序列是 1,1,2,3,5,8,13,数字 8 的序列是 1,1,2,3,5…...
学习raft协议(1)
CAP C: 一致性 强调数据的正确性,每次读操作,要么读到最新,要么读失败 A:可用性 不发生错误,也不能出现过长的等待时间. P:分区容错性 在网络环境不可靠的背景下,整个系统仍然是正常运作的两种流派 (1&am…...
SpringSecurity+jwt使用
参考文章链接 自定义SpringSecurity用户 package com.daben.springsecurityjwt.vo;import com.daben.springsecurityjwt.entity.SysUser; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.User; import j…...
html-网站菜单-点击显示导航栏
一、效果图 1.点击显示菜单栏,点击x号关闭; 2.点击一级菜单,展开显示二级,并且加号变为减号; 3.点击其他一级导航,自动收起展开的导航。 二、代码实现 <!DOCTYPE html> <html><head>&…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
