带你学LRU算法-非常简单好用

LRU(Least Recently Used)算法用于资源管理,当资源不足时淘汰使用频率低的资源。其核心思想是使用双向链表按时间顺序排列,并通过头部更新访问记录。在实现时,考虑线程安全通常需要对哈希表加锁,以保证并发环境下的正确性。高吞吐的LRU设计则需要优化读写操作对哈希表的影响。
摘要由CSDN通过智能技术生成

前言

名字听起来挺高大上的,其实内部的原理非常简单,英文全称是Least Recently Used,即最近最少使用算法。

正文

这算法最初还是源自Linux的内存管理。核心的思想就是,当出现资源不够用的时候,可以把那些使用频率低的资源给释放掉,然后拿来用!这样看起来还是很凶残的,那我举一格例子,是小灰的漫画算法中提到的。
用户在访问数据库的时候,程序员会为此做一些缓存记录,以便下一次用户再次访问同样的数据时可以避免磁盘操作,听起来还是很不错的对吧。
可是这个缓存咱们不能无限整下去,不然内存都不够你用的。

核心

将key-value数据对,或者是其他方式的资源,按照时间顺序,进行排序。然后用双向链表将这些数据对,统一起来。当一个资源被重新访问时,就将其放到链表的头部(相当于越是靠近链表头部的就越新),直到某次插入面临资源不足的情况了,就将链表的最后一个删除掉。

代码实现

实在是太简单了,咱们就不浪费时间了好吧。我去网上随便偷一下别人的代码实现这事儿就算过去了。

public class LRU<K,V> {
 
  private static final float hashLoadFactory = 0.75f;
  private LinkedHashMap<K,V> map;
  private int cacheSize;
 
  public LRU(int cacheSize) {
    this.cacheSize = cacheSize;
    int capacity = (int)Math.ceil(cacheSize / hashLoadFactory) + 1;
    map = new LinkedHashMap<K,V>(capacity, hashLoadFactory, true){
      private static final long serialVersionUID = 1;
 
      @Override
      protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > LRU.this.cacheSize;
      }
    };
  }
 
  public synchronized V get(K key) {
    return map.get(key);
  }
 
  public synchronized void put(K key, V value) {
    map.put(key, value);
  }
 
  public synchronized void clear() {
    map.clear();
  }
 
  public synchronized int usedSize() {
    return map.size();
  }
 
  public void print() {
    for (Map.Entry<K, V> entry : map.entrySet()) {
      System.out.print(entry.getValue() + "--");
    }
    System.out.println();
  }
}

如何设计一个高吞吐且线程安全的LRU

这应该才是我想看的东西,上面那些就很入门。咱们先考虑一下线程安全该如何实现。咱们首先得明确一个概念,就是LRU究竟是双链表还是哈希表。我认为,LRU本质上还是哈希表,只是哈希的value是带有双链表的东西。所以线程安全,本质上说的是哈希表的线程安全。(上面那份代码我找的不合适,感觉那是人家语言封装好的东西)
所以给哈希表上个锁就很棒了。
那么高吞吐呢?
很明显,不管是读操作还是写操作,最后都要修改这个哈希表,这是制约吞吐的关键因素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值