Java中的LRU缓存实现

San*_*eep 6 java concurrency multithreading caching lru

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

while(concurrentLinkedQueue.size() >=maxSize)
Run Code Online (Sandbox Code Playgroud)

围绕这个的任何指针都会很棒.

这是实施:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

rma*_*how 0

我想,这里的要点是,您需要检查 LRU 是否处于其最大大小。这里的检查不是 (map.size() > maxSize),而是 ">=。现在,您可能可以用“if (map.size() == maxSize) {...}”替换它 - 在理想条件下,它应该做完全相同的事情。

但在不太理想的情况下,如果出于某种原因,有人在没有检查的情况下在地图中添加了额外的条目,那么使用此代码,地图的大小将永远不会再次减小,因为 if 条件永远不会成立。

那么-为什么不使用“while”和“">=”而不是“if”和“==”呢?相同数量的代码,并且针对“意外”情况更加稳健。