Java中的LRU缓存实现

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

while(concurrentLinkedQueue.size() >=maxSize) 

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

这是实施:

 public class LRUCache { private ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue(); private ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); 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){…}”替换它 – 在理想条件下,它应该做同样的事情。

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

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

LRU缓存的简单实现如下所示,while循环仅在调整max size时需要,但不适用于原始操作:

  • 在放置期间,移除超级元素。
  • 在get期间,将元素移动到顶部。

原始操作将是一次性的。 然后,您可以在此数据结构周围使用普通的同步或读写锁。

当使用读写锁时,对谁来说的公平性是使用的读写锁的问题而不是LRU缓存本身的问题。

这是一个示例实现。