lru java实现_用链表实现一个简单的LRU(java)

LRU简介

LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。 该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当须淘汰一个页面时,选择现有页面中其t 值最大的,即最近最少使用的页面予以淘汰。

Redis中的LRU

当需要从缓存中淘汰数据时,我们希望淘汰那些将来不可能再被使用的数据,保留那些将来还会频繁访问的数据。

一个解决方法就是通过LRU进行预测:最近被频繁访问的数据将来被访问的可能性也越大。缓存中的数据一般会有这样的访问分布:一部分数据拥有绝大部分的访问量。

当访问模式很少改变时,可以记录每个数据的最后一次访问时间,拥有最少空闲时间的数据可以被认为将来最有可能被访问到。

配置参数

Redis配置中和LRU有关的有三个:

maxmemory:配置Redis存储数据时指定限制的内存大小,比如100m。当缓存消耗的内存超过这个数值时, 将触发数据淘汰。如果配置为0时,表示缓存的数据量没有限制。

maxmemory_policy:触发数据淘汰后的淘汰策略

maxmemory_samples: 随机采样的精度,也就是随即取出key的数目。该数值配置越大, 越接近于真实的LRU算法,但是数值越大,相应消耗也变高,对性能有一定影响。

淘汰策略

淘汰策略即maxmemory_policy的赋值有以下几种:

noeviction:如果缓存数据超过了maxmemory限定值,并且客户端正在执行的命令(大部分的写入指令,但DEL和几个指令例外)会导致内存分配,则向客户端返回错误响应

allkeys-lru: 对所有的键都采取LRU淘汰

volatile-lru: 仅对设置了过期时间的键采取LRU淘汰

allkeys-random: 随机回收所有的键

volatile-random: 随机回收设置过期时间的键

volatile-ttl: 仅淘汰设置了过期时间的键---淘汰生存时间TTL(Time To Live)更小的键

链表实现一个简单的LRU

package com.stone.java001;

public class LRUForLinkList {

private LRUNode headNode;

// 容量大小,类比与redis设置的maxmemory大小

private Integer capacity;

// 实际元素长度

private Integer length;

public LRUForLinkList() {

this.headNode = new LRUNode();

this.capacity = 10;

this.length = 0;

}

//插入数据

public void add(Integer data) {

//判断要插入的数据是否存在,如果存在,删除存在的元素,将该元素插入进头部

//如果不存在,判断是否超出容量,如果超出容量,删除最后一个元素,将该元素插入头部

LRUNode preNode = findPreNode(data);

if (preNode != null) {

delNode(preNode);

insertBegin(data);

} else {

if (length >= capacity) {

delEndNode();

}

insertBegin(data);

}

}

//在头部插入元素

public void insertBegin(Integer data) {

this.headNode.setNext(new LRUNode(data, this.headNode.getNext()));

length++;

}

//找到该元素的前一个节点

public LRUNode findPreNode(Integer data) {

LRUNode node = this.headNode;

while (node.getNext() != null) {

if (data.equals(node.getNext().getData())) {

return node;

}

node = node.getNext();

}

return null;

}

//删除指定值的元素

public void delNode(LRUNode preNode) {

LRUNode tmp = preNode.getNext();

preNode.setNext(tmp.getNext());

tmp = null;

length--;

}

//删除末尾节点

public void delEndNode() {

LRUNode ptr = headNode;

if (ptr.getNext() == null) {

return;

}

while (ptr.getNext().getNext() != null) {

ptr = ptr.getNext();

}

LRUNode tmp = ptr.getNext();

ptr.setNext(null);

tmp = null;

length--;

}

//打印该链表

private void printAll() {

LRUNode node = headNode.getNext();

while (node != null) {

System.out.print(node.getData() + ",");

node = node.getNext();

}

System.out.println();

}

//测试。。。

public static void main(String[] args) {

LRUForLinkList lruForLinkList = new LRUForLinkList();

for(int i=0;i<10;i++){

lruForLinkList.add(i);

}

lruForLinkList.printAll();

lruForLinkList.add(8);

lruForLinkList.printAll();

lruForLinkList.add(11);

lruForLinkList.printAll();

}

}

class LRUNode {

private Integer data;

private LRUNode next;

public LRUNode() {

this.next = null;

}

public LRUNode(Integer data) {

this.data = data;

}

public LRUNode(Integer data, LRUNode next) {

this.data = data;

this.next = next;

}

public Integer getData() {

return data;

}

public void setData(Integer data) {

this.data = data;

}

public LRUNode getNext() {

return next;

}

public void setNext(LRUNode next) {

this.next = next;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值