Java中的LRU缓存实现 [英] LRU Cache Implementation in Java

查看:142
本文介绍了Java中的LRU缓存实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到了以下代码,我认为在addElement方法的实现中有一个无用的while循环。它应该永远不会出现比size + 1更多的元素,因为已经存在写锁定。
那么为什么addElement方法删除元素直到它获得这个条件
true

I have seen the following code, and I think that there is a useless while loop in the implementation of addElement method. It should never happen to have more elements than size+1 since there is already a write lock. So why is the addElement method removing elements till it gets this condition true

while(concurrentLinkedQueue.size() >=maxSize)

任何关于此的指针都会很棒。

Any pointers around this would be great.

以下是实施:

public class  LRUCache<K,V> {

    private  ConcurrentLinkedQueue<K> concurrentLinkedQueue = new ConcurrentLinkedQueue<K>();

    private  ConcurrentHashMap<K,V> concurrentHashMap = new ConcurrentHashMap<K, V>();

    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    private Lock readLock = readWriteLock.readLock();

    private Lock writeLock = readWriteLock.writeLock();

    int maxSize=0;

    public LRUCache(final int MAX_SIZE){
        this.maxSize=MAX_SIZE;
    }

    public V getElement(K key){

        readLock.lock();
        try {
        V v=null;
          if(concurrentHashMap.contains(key)){
              concurrentLinkedQueue.remove(key);
              v= concurrentHashMap.get(key);
                concurrentLinkedQueue.add(key);
          }


        return v;
        }finally{
            readLock.unlock();
        }
    }

    public V removeElement(K key){
         writeLock.lock();
         try {
        V v=null;
        if(concurrentHashMap.contains(key)){
        v=concurrentHashMap.remove(key);
            concurrentLinkedQueue.remove(key);
        }

        return v;
         } finally {
             writeLock.unlock();
         }
    }

    public V addElement(K key,V value){
        writeLock.lock();
        try {
        if(concurrentHashMap.contains(key)){
             concurrentLinkedQueue.remove(key);
        }
        while(concurrentLinkedQueue.size() >=maxSize){
             K queueKey=concurrentLinkedQueue.poll();
             concurrentHashMap.remove(queueKey);
        }
        concurrentLinkedQueue.add(key);
        concurrentHashMap.put(key, value);

        return value;
        } finally{
            writeLock.unlock();
        }
    }
}


推荐答案

这里的观点是,我想,你需要检查LRU是否达到它的最大尺寸。这里的检查是NOT(map.size()> maxSize),它是> =。现在,你可以用if(map.size()== maxSize){...}替换它 - 在理想条件下,它应该做同样的事情。

the point here is, i guess, that you need to check if the LRU is at it's maximum size. the check here is NOT (map.size() > maxSize), it is ">=". now, you could probably replace that with "if (map.size() == maxSize) {...}" - which, in ideal conditions, should do exactly the same thing.

但是在不太理想的条件下,如果出于某种原因,有人在地图中放入了EXTRA条目而没有检查,那么使用此代码,地图永远不会去再次缩小规模,因为if条件永远不会成立。

but in not-so-ideal conditions, if for whatever reason, somebody put an EXTRA entry in the map without checking, then with this code, the map would NEVER go down in size again, because the if condition would never be true.

所以 - 为什么不while和> =而不是if和== ?相同数量的代码,以及对意外条件的更强大。

so - why not "while" and ">=" instead of "if" and "=="? same amount of code, plus more robust against "unexpected" conditions.

这篇关于Java中的LRU缓存实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆