java - Java 中的 LRU 缓存实现

标签 java multithreading caching concurrency lru

我看过下面的代码,我认为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/

相关文章:

c - 如何将特定值传递给一个线程?

java - 是否有用于缓存文件的 Java 库?

Java SSL连接,以编程方式将服务器证书添加到 keystore

java - 什么是NullPointerException,我该如何解决?

java - JBoss AS7中如何获取EJB方法的调用远程客户端地址

c++ - 写同步读成功

java - 从 Java 类自定义 Granite DS Actionscript 代码生成

multithreading - 斯坦福解析器多线程使用

linux - 如何为用户清除 linux 机器上的缓存内存?

file - hadoop中的分布式缓存