用HashMap和双链表实现多线程下的LRU缓存算法(java版)

缓存的目的:缓存主要为了保存数据的,在项目中,开启服务器的时候,将大量被访问的数据从数据库中查到,放入到缓存中,服务器开启后,用户从前端向后台发送请求,直接从缓存中去取,不用查数据库,加快数据的访问。

我的缓存的需求:主要想保存ArticleBean(中有很多属性),加入到缓存的时候按照点击量的降序,定时更新缓存的时候能将按照点击量的降序加入到合适的位置,而查找文章的时候需要根据文章的id直接缓存中去获取,不需要遍历。

思路:
链表:插入到合适的位置,不需要数据的移动
HashMap:直接根据文章的id获取ArticleBean对象。
假设:
如果将数据分别保存到链表和HashMap中,那么数据保存了两份,占用了两份内存,在内存宝贵的情况下这样是不行的。
所以:
将ArticleBean转化为一个节点Entry,在节点中保存ArticleBean作为value、前一个节点,后一个节点,key作为键值。
好处:
1.保存在HashMap可以直接定位节点的位置
2.用节点连接起来又可以直接插入节点
3.每个节点在缓存中只有这一份

多线程:
用读写锁来实现多线程下的安全,当增加、移动、删除的时候用写锁,而查阅的时候用读锁。

我的代码:

package com.zhangyike.lru;

import java.util.HashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class MyLRU<K,V> {
    private int cacheSize;//缓存的长度
    private HashMap<K, Entry<K,V>> nodes;//缓存容器,node的建其实就是Entry的键
    private int currentSize;//缓存中的元素长度
    private Entry<K,V> head;//链表的头部
    private Entry<K,V> tail;//链表的尾部

    /*
     * 该类对象,保证该类对象在服务器上只有一份。
     */
    private static MyLRU instance;
    private static ReadWriteLock rwl = new ReentrantReadWriteLock();//用于修改缓存中数据的读写锁
    private static ReadWriteLock rwlInstance = new ReentrantReadWriteLock();//用于创建对象的读写锁

    /*
     * 虽然getLruThread(..)方法中加了rwl.writeLock().lock();,为了以防万一,该方法中也要加锁。
     * 这样不会造成死锁,属于可重入锁,这两个锁的对象是相同的,就不会重新申请锁了。
     */
    private MyLRU(int cacheSize){
        rwlInstance.writeLock().lock();
        try{
            this.cacheSize = cacheSize;
            currentSize = 0;
            nodes = new HashMap<K,Entry<K,V>>(cacheSize);//根据提供的参数初始化容器初始化容器
        }finally{
            rwlInstance.writeLock().unlock();
        }
    }

    public static MyLRU getLruThread(){
        return getLruThread(16);
    }

    public static MyLRU getLruThread(int cacheSize){
        //多个线程可以同时去读这个对象,
        rwl.readLock().lock();;
        
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值