当前位置: 首页 > news >正文

Java失效算法与应用(FIFO、LRU、LFU)

文章目录

  • 一、什么是失效算法
  • 二、先来先淘汰(FIFO)
    • 1、FIFO概述
    • 2、Java实现FIFO
    • 3、FIFO特点
  • 三、最久未用淘汰(LRU)
    • 1、LRU概述
    • 2、Java实现LRU
  • 四、最近最少使用(LFU)
    • 1、LFU概述
    • 2、Java实现LFU
  • 五、应用案例

一、什么是失效算法

失效算法常见于缓存系统中。因为缓存往往占据大量内存,而内存空间是相对昂贵,且空间有限的,那么针对一部分值,就要依据相应的算法进行失效或移除操作。

二、先来先淘汰(FIFO)

1、FIFO概述

First In First Out,先来先淘汰。这种算法在每一次新数据插入时,如果队列已满,则将最早插入的数据移除

2、Java实现FIFO

可以方便的借助LinkedList来实现。

public class FIFO {LinkedList<Integer> fifo = new LinkedList<Integer>();int size = 3;//添加元素public void add(int i){fifo.addFirst(i);if (fifo.size() > size){fifo.removeLast();}print();}//缓存命中public void read(int i){Iterator<Integer> iterator = fifo.iterator();while (iterator.hasNext()){int j = iterator.next();if (i == j){System.out.println("find it!");print();return ;}}System.out.println("not found!");print();}//打印缓存public void print(){System.out.println(this.fifo);}//测试public static void main(String[] args) {FIFO fifo = new FIFO();System.out.println("add 1-3:");fifo.add(1);fifo.add(2);fifo.add(3);System.out.println("add 4:");fifo.add(4);System.out.println("read 2:");fifo.read(2);System.out.println("read 100:");fifo.read(100);System.out.println("add 5:");fifo.add(5);}
}

结果:
add 1-3:
[1]
[2, 1]
[3, 2, 1]
add 4:
[4, 3, 2]
read 2:
find it!
[4, 3, 2]
read 100:
not found!
[4, 3, 2]
add 5:
[5, 4, 3]
Process finished with exit code 0

3、FIFO特点

我们发现,FIFO实现非常简单,不管元素的使用情况,哪怕有些数据会被频繁用到,时间最久也会被踢掉(不太理性)。

三、最久未用淘汰(LRU)

1、LRU概述

LRU全称是Least Recently Used,即淘汰最后一次使用时间最久远的数值。FIFO非常的粗暴,不管有没有用到,直接踢掉时间久的元素。而LRU认为,最近频繁使用过的数据,将来也很大程度上会被频繁用到,故而淘汰那些懒惰的数据。

2、Java实现LRU

LinkedHashMap,数组,链表均可实现LRU,下面仍然以链表为例:新加入的数据放在头部,最近访问的,也移到头部,空间满时,将尾部元素删除。

public class LRU {LinkedList<Integer> lru = new LinkedList<Integer>();int size = 3;//添加元素public void add(int i){lru.addFirst(i);if (lru.size() > size){lru.removeLast(); // 删除尾部元素}print();}//缓存命中public void read(int i){Iterator<Integer> iterator = lru.iterator();int index = 0;while (iterator.hasNext()){int j = iterator.next();if (i == j){System.out.println("find it!");// 被访问的元素移到头部lru.remove(index);lru.addFirst(j);print();return ;}index++;}System.out.println("not found!");print();}//打印缓存public void print(){System.out.println(this.lru);}//测试public static void main(String[] args) {LRU lru = new LRU();System.out.println("add 1-3:");lru.add(1);lru.add(2);lru.add(3);System.out.println("add 4:");lru.add(4);System.out.println("read 2:");lru.read(2);System.out.println("read 100:");lru.read(100);System.out.println("add 5:");lru.add(5);}
}

结果:
add 1-3:
[1]
[2, 1]
[3, 2, 1]
add 4:
[4, 3, 2]
read 2:
find it!
[2, 4, 3]
read 100:
not found!
[2, 4, 3]
add 5:
[5, 2, 4]

四、最近最少使用(LFU)

1、LFU概述

Least Frequently Used,即最近最少使用。它要淘汰的是最近一段时间内,使用次数最少的值。可以认为比LRU多了一重判断。LFU需要时间和次数两个维度的参考指标。

需要注意的是,两个维度就可能涉及到同一时间段内,访问次数相同的情况,就必须内置一个计数器和一个队列,计数器算数,队列放置相同计数时的访问时间。

2、Java实现LFU

public class Dto implements Comparable<Dto> {private Integer key;private int count;private long lastTime;public Dto(Integer key, int count, long lastTime) {this.key = key;this.count = count;this.lastTime = lastTime;}@Overridepublic int compareTo(Dto o) {int compare = Integer.compare(this.count, o.count);return compare == 0 ? Long.compare(this.lastTime, o.lastTime) : compare;}@Overridepublic String toString() {return String.format("[key=%s,count=%s,lastTime=%s]",key,count,lastTime);}public Integer getKey() {return key;}public void setKey(Integer key) {this.key = key;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public long getLastTime() {return lastTime;}public void setLastTime(long lastTime) {this.lastTime = lastTime;}
}
public class LFU {private final int size = 3;private Map<Integer,Integer> cache = new HashMap<>();private Map<Integer, Dto> count = new HashMap<>();//投放public void put(Integer key, Integer value) {Integer v = cache.get(key);if (v == null) {if (cache.size() == size) {removeElement();}count.put(key, new Dto(key, 1, System.currentTimeMillis()));} else {addCount(key);}cache.put(key, value);}//读取public Integer get(Integer key) {Integer value = cache.get(key);if (value != null) {addCount(key);return value;}return null;}//淘汰元素private void removeElement() {Dto dto  = Collections.min(count.values());cache.remove(dto.getKey());count.remove(dto.getKey());}//更新计数器private void addCount(Integer key) {Dto Dto = count.get(key);Dto.setCount(Dto.getCount()+1);Dto.setLastTime(System.currentTimeMillis());}//打印缓存结构和计数器结构private void print(){System.out.println("cache="+cache);System.out.println("count="+count);}public static void main(String[] args) {LFU lfu = new LFU();//前3个容量没满,1,2,3均加入System.out.println("add 1-3:");lfu.put(1, 1);lfu.put(2, 2);lfu.put(3, 3);lfu.print();//1,2有访问,3没有,加入4,淘汰3System.out.println("read 1,2");lfu.get(1);lfu.get(2);lfu.print();System.out.println("add 4:");lfu.put(4, 4);lfu.print();//2=3次,1,4=2次,但是4加入较晚,再加入5时淘汰1System.out.println("read 2,4");lfu.get(2);lfu.get(4);lfu.print();System.out.println("add 5:");lfu.put(5, 5);lfu.print();}
}

五、应用案例

redis属于缓存失效的典型应用场景,常见策略如下:

noeviction: 不删除策略, 达到最大内存限制时, 如果需要更多内存, 直接返回错误信息( 比较危险)。
allkeys-lru:对所有key,优先删除最近最少使用的 key (LRU)。
allkeys-random: 对所有key, 随机删除一部分(听起来毫无道理)。
volatile-lru:只限于设置了 expire 的key,优先删除最近最少使用的key (LRU)。
volatile-random:只限于设置了 expire 的key,随机删除一部分。
volatile-ttl:只限于设置了 expire 的key,优先删除剩余时间(TTL) 短的key。

相关文章:

Java失效算法与应用(FIFO、LRU、LFU)

文章目录 一、什么是失效算法二、先来先淘汰&#xff08;FIFO&#xff09;1、FIFO概述2、Java实现FIFO3、FIFO特点 三、最久未用淘汰&#xff08;LRU&#xff09;1、LRU概述2、Java实现LRU 四、最近最少使用&#xff08;LFU&#xff09;1、LFU概述2、Java实现LFU 五、应用案例 …...

Go语音介绍

Go语言介绍 Go 即Golang&#xff0c;是Google公司2009年11月正式对外公开的一门编程语言。 Go是静态强类型语言&#xff0c;是区别于解析型语言的编译型语言。 解析型语言——源代码是先翻译为中间代码&#xff0c;然后由解析器对代码进行解释执行。 编译型语言——源代码编…...

Vue2与Vue3响应式原理

Vue2的响应式 Vue3的响应式...

flask中写一个基础的sqlHelper类

写一个SQLHelper类&#xff1a; from flask_sqlalchemy import SQLAlchemydb SQLAlchemy()class SQLHelper:staticmethoddef add(record):db.session.add(record)return SQLHelper.session_commit()staticmethoddef add_all(records):db.session.add_all(records)return SQLH…...

opencv的Mask操作,选择图片中感兴趣的区域

最近做目标检测任务的时候&#xff0c;需要对固定区域的内容进行检测&#xff0c;要用到opencv的mask操作&#xff0c;选择图片固定的区域 代码 import cv2 import numpy as npimg cv2.imread(data/images/smoking.png)# 弹出一个框 让你选择ROI | x,y是左上角的坐标 x,y,w,…...

一次有趣的Webshell分析经历

一次有趣的Webshell分析经历 1.拉取源代码2.解密后门代码3.分析webshell逻辑4.分析404的原因5.附&#xff1a;格式化后的php代码 1.拉取源代码 在对某目标做敏感目录收集时发现对方网站备份源代码在根目录下的 backup.tar.gz&#xff0c;遂下载&#xff0c;先使用D盾分析有没有…...

【NLP概念源和流】 05-引进LSTM网络(第 5/20 部分)

一、说明 在上一篇博客中,我们讨论了原版RNN架构,也讨论了它的局限性。梯度消失是一个非常重要的缺点,它限制了RNN对较短序列的建模。香草 RNN 在相关输入事件和目标信号之间存在超过 5-10 个离散时间步长的时间滞时无法学习。这基本上限制了香草RNN在许多实际问题上的应用,…...

Vue没有node_modules怎么办

npm install 一下 然后再npm run serve 就可以运行了...

企业级高负载web服务器-Tomcat小项目

目录 web静态动态页面区别安装java环境安装Tomcat安装Tomcat包到目录查看Tomcat主目录结构查看Tomcat配置目录结构Tomcat管理Tomcat web管理功能 部署jpress应用 web静态动态页面区别 静态页面&#xff1a; 在网站设计中&#xff0c;纯粹HTML格式的网页&#xff08;可以包含图…...

《golang设计模式》第一部分·创建型模式-03-建造者模式(Builder)

文章目录 1. 概念1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概念 1.1 角色 Builder&#xff08;抽象建造者&#xff09;&#xff1a;给出一个抽象接口&#xff0c;以规范产品对象的各个组成成分的建造。ConcreteBuilder&#xff08;具体建造者&#xff09;&a…...

git 忽略掉不需要的文件

第一步&#xff1a;创建.gitignore文件 touch .gitignore 第二步&#xff1a;使用vi编辑器 输入不需要的文件&#xff0c;或用通配符*来忽视一系列文件 效果&#xff1a;...

摄像机sd卡格式化怎么恢复数据?简单五步轻松解决

在使用摄像机时&#xff0c;有时不慎将SD卡格式化&#xff0c;导致重要的照片或视频文件丢失。然而&#xff0c;不必惊慌&#xff0c;本文将详细解释如何恢复被格式化的摄像机SD卡上的数据&#xff0c;可通过下面提供的五步&#xff0c;轻松解决数据丢失问题&#xff0c;以确保…...

1-4 AUTOSAR方法论--开发流程

目录 一、方法论 二、单个ECU开发流程 一、方法论 AUTOSAR 方法论&#xff08;AUTOSAR Methodology&#xff09;中车用控制器软件的开发涉及系统级、ECU 级的开发。 系统级&#xff1a;主要考虑系统功能需求、硬件资源、系统约束&#xff0c;然后建立系统架构&#xff1b; 输…...

Win10查询硬盘序列号

添加wmic命令 winR cmd命令 wmic diskdrive get model, serialnumber...

减少错误和重复工作:PDM系统的智能排错功能

减少错误和重复工作&#xff1a;PDM系统的智能排错功能 在产品开发和制造过程中&#xff0c;错误和重复工作常常是企业面临的挑战。这不仅浪费了宝贵的时间和资源&#xff0c;还可能导致产品质量下降和生产延误。PDM系统&#xff08;Product Data Management&#xff0c;产品数…...

【面试题】作用域面试题

作用域 全局作用域局部作用域&#xff08;函数里&#xff09;也称函数作用域块级作用域 {}包裹的 例如if for 括号&#xff08;&#xff09;也算 变量 全局变量 谁都能用&#xff0c;在函数内也可以局部变量&#xff0c;只能在该函数内用&#xff0c;如果这个函数嵌套了子函…...

08 定时器(下)

08 定时器&#xff08;下&#xff09; 本文内容 定时器处理非活动连接模块&#xff0c;分为定时方法与信号通知流程&#xff1b;定时器及其容器设计、定时任务的处理。 定时器设计&#xff0c;将连接资源与定时事件等封装起来&#xff0c;具体包括连接资源、超时时间和回调函…...

C++设计模式之适配器设计模式

文章目录 C适配器设计模式什么是适配器设计模式该模式有什么优缺点优点缺点 如何使用 C适配器设计模式 什么是适配器设计模式 适配器设计模式是一种行为型设计模式&#xff0c;它允许你将两个不兼容的接口组合在一起&#xff0c;使它们能够协同工作。 该模式有什么优缺点 优…...

Maven项目解决cannot resolve plugin maven-deploy-plugin:2.7

导入maven项目后&#xff0c;编辑的时候提示一些插件加载失败&#xff01;大概率是你的网络有问题&#xff0c;插件下载失败。 如下图&#xff1a;&#xff08;网络突然好了&#xff0c;我想截图但是没有复现&#xff0c;用网上找到的截图代替&#xff0c;明白意思就行&#x…...

Postgresql源码(110)分析dsm动态共享内存分配与共享内存mq实例

相关 《Postgresql源码&#xff08;90&#xff09;共享内存申请CreateSharedMemoryAndSemaphores》 《Linux内存映射函数mmap与匿名内存块》 《Linux共享内存与子进程继承》 0 概念 数据结构含义&#xff1a; dsm_segment&#xff08;动态共享内存段&#xff09;&#xff1a;…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...