我看过下面的代码,我认为addElement方法的实现中有一个无用的while循环。它不应该碰巧有比 size+1 更多的元素,因为已经有一个写锁。 那么为什么 addElement 方法要删除元素直到它得到这个条件 是的
while(concurrentLinkedQueue.size() >=maxSize)
任何关于此的指示都会很棒。
这里是实现:
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 是否处于最大大小。这里的检查不是 (map.size() > maxSize),而是“>=”。现在,您可能可以将其替换为“if (map.size() == maxSize) {...}”——在理想情况下,它应该做完全相同的事情。
但是在不太理想的条件下,如果出于某种原因,有人在没有检查的情况下在 map 中放置了一个额外的条目,那么使用这段代码, map 将永远不会再次缩小,因为 if 条件永远不会是的。
所以 - 为什么不用“while”和“>=”而不是“if”和“==”?相同数量的代码,加上针对“意外”情况的更强大。
关于java - Java 中的 LRU 缓存实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30129960/