【发布时间】:2015-07-19 17:33:24
【问题描述】:
我看过下面的代码,觉得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();
}
}
}
【问题讨论】:
-
仅供参考:
ConcurrentLinkedQueue#size需要全面扫描,而ConcurrentHashMap#size会被跟踪。您的实现是 O(n),而有效的实现是 O(1)。您可能有兴趣阅读并发 LRU 缓存的design。 -
您可以在以下链接找到有效的解决方案:stackoverflow.com/questions/6398902/…
-
既然线程安全是通过使用锁来保证的,我相信没有必要使用并发版本的map和queue。这只是开销
标签: java multithreading caching concurrency lru