根据优先级 + LRU 缓存数据

文章目录

  • 前言
  • 一、优先级队列
    • PriorityQueue 简介
  • 二、优先级+LRU
  • 总结


前言

在项目中遇到了,需要根据 优先级 + LRU 缓存数据;


LRU 优先考虑采用hutool ,然后自己附加搞上 一个优先级就行了

一、优先级队列

PriorityQueue 简介

  1. PriorityQueue是基于优先级堆的无界队列。

  2. PriorityQueue的作用是保证每次取出的都是队列中权值最小的元素,也可以说是最高优先级的元素。

  3. PriorityQueue的元素排序是按照自然排序来进行排序的,在创建时可以给他添加一个给元素排序的比较器。

offer():添加元素到队列中,如果队列已满,则返回false。
poll():检索并删除队列中的最小元素,如果队列为空,则返回null。
remove():检索并删除队列中的最小元素,如果队列为空,则返回null。
add():添加元素到队列中。
peek():检索但不删除队列中的最小元素,如果队列为空,则返回null。
size():返回队列中的元素数目。
iterator():返回一个迭代器,该迭代器可以按排序的顺序遍历队列中的元素。

二、优先级+LRU

由于PriorityQueue 是无界队列,所以需要保证队列长度不超过最大值
由于每次获取的都是优先级最高的元素,所以采用倒叙,也就是优先级高的在最后 ,数值越小越靠后,优先级越高
采用读写锁,控制并发


import cn.hutool.cache.CacheListener;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.LRUCache;
import cn.hutool.json.JSONUtil;
import java.util.AbstractMap;
import java.util.Comparator;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.springframework.util.ObjectUtils;/*** 根据优先级 + LRU 缓存数据** @author fulin* @since 2023/11/15 16:11*/
public class PriorityLRUCache {private PriorityLRUCache() {}// 存储最大值private static int maxSize = 3;// 缓存时间 单位msprivate static int time = 90000;public static void setMaxSize(int maxSize) {PriorityLRUCache.maxSize = maxSize;}public static void setTime(int time) {PriorityLRUCache.time = time;}// lru 存储 单位msprivate static final LRUCache<Object, Object> lruCache = CacheUtil.newLRUCache(maxSize * 2,time);// 优先级队列,存储键值对,并根据使用频率排序 降序,优先级高的在最后// 数值越小越靠后,优先级越高private static final PriorityQueue<Entry<Object, Integer>> priorityQueue = new PriorityQueue<>(maxSize, Comparator.comparingInt(o -> -(o.getValue())));private static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();private static final Lock writeLock = readWriteLock.writeLock();private static final Lock readLock = readWriteLock.readLock();/*** 按照优先级添加元素* <p>超过限制将移除优先级最低元素,优先级相等则以最后新增元素为主</p>** @param key      元素 key* @param priority 元素优先级* @param value    元素 value*/public static void put(Object key, Integer priority, Object value) {writeLock.tryLock();try {if (ObjectUtils.isEmpty(priorityQueue)) {addElement(key, priority, value);return;}// 先从优先级队列中移除旧的元素if (priorityQueue.contains(key)) {priorityQueue.remove(key);lruCache.remove(key);}// 添加新的元素到优先级队列和缓存中addElement(key, priority, value);if (priorityQueue.size() > maxSize) {Entry<Object, Integer> peek = priorityQueue.peek();lruCache.remove(peek.getKey());priorityQueue.poll();}} finally {writeLock.unlock();}}/*** 添加新的元素到优先级队列和缓存中** @param key      元素 key* @param priority 元素优先级* @param value    元素 value*/private static void addElement(Object key, Integer priority, Object value) {priorityQueue.add(new AbstractMap.SimpleEntry<>(key, priority));lruCache.put(key, value);}/*** 根据 key 获取缓存的值** @param key 缓存 key* @return 缓存的 value*/public static Object get(Object key) {readLock.tryLock();try {if (lruCache.containsKey(key)) {return lruCache.get(key);} else {return null;}} finally {readLock.unlock();}}/*** 获取无序 key 集合** @return 无序 key 集合*/public static Object getPriorityQueue() {return priorityQueue;}/*** 获取当前最低优先级元素 <li>kye,优先级</li>** @return 最低优先级元素*/public static Entry<Object, Integer> getMinPriorityElement() {return priorityQueue.peek();}/*** 设置缓存监听** @param listener 监听类*/public static void setListener(CacheListener<Object, Object> listener) {lruCache.setListener(listener);}public static void main(String[] args) {PriorityLRUCache.put("a", 1, 8);PriorityLRUCache.put("b", 2, 9);PriorityLRUCache.put("c", 3, 7);System.out.println(JSONUtil.toJsonPrettyStr(PriorityLRUCache.getPriorityQueue()));System.out.println(PriorityLRUCache.get("a"));System.out.println(PriorityLRUCache.get("b"));System.out.println(PriorityLRUCache.get("c"));// 低优先级添加PriorityLRUCache.put("d", 7, 6);// 高优先级添加
//    PriorityLRUCache.put("d", 2, 6);// 同优先级添加
//    PriorityLRUCache.put("d", 3, 5);System.out.println(JSONUtil.toJsonPrettyStr(PriorityLRUCache.getPriorityQueue()));System.out.println(PriorityLRUCache.get("a"));System.out.println(PriorityLRUCache.get("b"));System.out.println(PriorityLRUCache.get("c"));System.out.println(PriorityLRUCache.get("d"));PriorityLRUCache.setListener((key, cachedObject) -> {System.out.println(key);System.out.println(cachedObject);});}
}

总结

看看长期使用效果如何吧,目前看问题不大,hutool真方便~,虽然站在巨人的肩膀上,做了点优先级的东西,但是还是收获颇丰的.

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

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

相关文章

家庭教育,培养娃什么最重要?

家庭教育&#xff0c;培养娃什么最重要&#xff1f; 培养能力最重要 &#xff08;我这么认为的&#xff09; 时代巨变&#xff0c;技术变革的非常快&#xff0c;所以总的来说 年轻一代接触的新东西慢慢比老一代的要多&#xff0c;年轻一代的工作会比老一代的多而且多很多&…

mybatis的流式查询

1&#xff1a;第一种&#xff1a;xml配置 <select id"selectFetchSize" fetchSize"100" resultSetType"FORWARD_ONLY" resultType"com.example.poi.entity.EntityDemo">select * from entity_demo</select>1-2&#xff1a…

char* 指针的数据,转为十六进制的字符串

目录 1、用CString的方式&#xff1a; 2、用 string 方式 前言&#xff1a; 有些字符串直接打印出来是乱码&#xff0c;显示不出来。于是要转为十六进制的字符&#xff0c;再打印出来。 C语言字符串转换为16进制&#xff1a;自定义转换函数 1、用CString的方式&#xff1a; …

【Python】实现一个简单的区块链系统

本文章利用 Python 实现一个简单的功能较为完善的区块链系统&#xff08;包括区块链结构、账户、钱包、转账&#xff09;&#xff0c;采用的共识机制是 POW。 一、区块与区块链结构 Block.py import hashlib from datetime import datetimeclass Block:"""区…

大数据-之LibrA数据库系统告警处理(ALM-37014 Gaussdb进程锁文件已经存在)

告警解释 当集群中的CN实例或者DN实例锁文件创建失败时&#xff0c;产生该告警。 告警属性 告警ID 告警级别 可自动清除 37014 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称 RoleName 产生告警的角色名称 HostName 产生告警的主机名 I…

Linux常用命令——ls 命令详解

文章目录 在Linux操作系统中&#xff0c;ls 命令是最常用且基础的命令之一。它用于列出目录内容&#xff0c;展示文件和目录的信息。本文将详细介绍ls 命令的各个参数及其含义&#xff0c;并通过实例演示它们的用法。 ls命令概述 ls 命令的基本格式为 ls [选项] [文件或目录]…

VirtualBox 7.0.8(虚拟机软件)

VirtualBox是一款开源的虚拟机软件&#xff0c;它是使用Qt编写&#xff0c;在Sun被Oracle收购后正式更名成Oracle VM VirtualBox。它可以在VirtualBox上安装并且执行Solaris、Windows、DOS、Linux、OS/2 Warp、BSD等系统作为客户端操作系统。使用者可以在VirtualBox上安装并且运…

stm32 计数模式

计数模式 但是对于通用定时器而言&#xff0c;计数器的计数模式不止向上计数这一种。上文基本定时器中计数器的计数模式都是向上计数的模式。 向上计数模式&#xff1a;计数器从0开始&#xff0c;向上自增&#xff0c;计到和自动重装寄存器的目标值相等时&#xff0c;计数器清…

C语言、c++史上最全最全爱心代码大全,彩色闪动、字符填充,附源码

第一种&#xff1a;红色爱心代码 直接上代码&#xff1a; #include<stdio.h> #include<Windows.h> int main() {system(" color 0c");//设计程序颜色 printf("遇见你是一件很开心的事情,爱你哟&#xff01;&#xff01;&#xff01;\n");//打…

面试阿里测开岗失败后,被面试官在朋友圈吐槽了......

前一阵子有个徒弟向我诉苦&#xff0c;说自己在参加某大厂测试面试的时候被面试官怼得哑口无言&#xff0c;场面让他一度十分尴尬 印象最深的就是下面几个问题&#xff1a; 根据你以前的工作经验和学习到的测试技术&#xff0c;说说你对质量保证的理解&#xff1f; 非关系型…

【数据结构】栈和队列---C语言版

栈和队列 一、栈的概念二、栈的实现三、栈的应用四、队列的概念五、队列的实现 一、栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守…

Unity 获取物体的子物体的方法

Unity 中要获取物体的子物体&#xff0c;可以使用以下一些方法。 1、只获取一级节点的子物体&#xff1a; public Transform tran;// Start is called before the first frame updatevoid Start(){foreach (Transform child in tran){Debug.Log(child.name);}} 使用该方法只会…

【古月居《ros入门21讲》学习笔记】08_发布者Publisher的编程实现

目录 说明&#xff1a; 1. 话题模型 图示 说明 2. 实现过程&#xff08;C&#xff09; 创建功能包 创建发布者代码&#xff08;C&#xff09; 配置发布者代码编译规则 编译并运行 编译 运行 3. 实现过程&#xff08;Python&#xff09; 创建发布者代码&#xff08;…

状态机模型 笔记

股票买卖 IV 给定一个长度为 N的数组&#xff0c;数组中的第 i 个数字表示一个给定股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润&#xff0c;你最多可以完成 k 笔交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之前…

解决tomcat 启动 , 中文乱码问题

解决tomcat 启动 , 中文乱码问题. 第一步找到server.xml, 找到连接器, 添加 URIEncoding"UTF-8" 注意是英文的引号. 第二步, 找到 logging.properties , 在其中找到 第三步,启动服务, 观察现象,亲测有效.

Django快速搭建静态网页

Django的快速搭建 这个是例子 这个是一个目录 项目名称&#xff1a;项目似乎被命名为DJ0928&#xff0c;这是Django项目的根目录。 文件都是Django项目的核心配置文件。 settings.py 包含了项目的配置设置。urls.py 定义了项目的URL路由。wsgi.py 和 asgi.py 分别用于Web服务器…

【Qt之QSqlRelationalDelegate】描述及使用

描述 QSqlRelationalDelegate类提供了一个委托&#xff0c;用于显示和编辑来自QSqlRelationalTableModel的数据。 与默认委托不同&#xff0c;QSqlRelationalDelegate为作为其他表的外键的字段提供了一个组合框。 要使用该类&#xff0c;只需在带有QSqlRelationalDelegate实例…

macbook电脑运行缓慢和卡顿内存怎么清理了?

假如你还在为“你的系统内存不足”的提示所困扰&#xff0c;或者你的Mac电脑突然运行缓慢和卡顿&#xff0c;那么你一般需要认真了解一下macbook内存怎么清理了? MacBook是功能强大的电脑&#xff0c;这点毫无疑问&#xff0c;但是它仍旧会随着时间推移变得运行缓慢。值得庆幸…

linux下恶意软件的七种反分析技术

7 类主流的 Linux 恶意软件反分析/检测躲避技术 反调试&#xff08;Anti-Debug&#xff09;: 软件调试是恶意软件分析的常⽤⼿段之⼀&#xff0c;但恶意软件可以通过识别调试器特征&#xff0c;实现⾃⾝恶意⾏为的隐藏&#xff0c;或导致调试失败&#xff0c;从⽽规避分析与检测…

二叉树OJ题之二

今天我们一起来看一道判断一棵树是否为对称二叉树的题&#xff0c;力扣101题&#xff0c; https://leetcode.cn/problems/symmetric-tree/ 我们首先先来分析这道题&#xff0c;要判断这道题是否对称&#xff0c;我们首先需要判断的是这颗树根节点的左右子树是否对称&#xff0…