Java 自定义LinkedHashMap并发

Java 自定义LinkedHashMap并发,java,Java,使此自定义LinkedHashMap自定义缓存示例线程安全的最佳方法是什么 public class Cache extends LinkedHashMap<Object, Object>{ private static final long serialVersionUID = -4297992703249995219L; private final int cacheSize; public Cache(int size){

使此自定义LinkedHashMap自定义缓存示例线程安全的最佳方法是什么

 public class Cache extends LinkedHashMap<Object, Object>{
        private static final long serialVersionUID = -4297992703249995219L;
        private final int cacheSize;
        public Cache(int size){
            super(size + 1, .75f, true); 
            this.cacheSize=size;
        }

         protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
            return size() > cacheSize;
         }
    }


public class Main {
    public static void main(String[] args) {
        Cache cache = new Cache(2);
        cache.put(1, "one");
        cache.put(2, "two");

        for(Entry<Object, Object> entry : cache.entrySet()){
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }
}

我建议您按照SLaks在评论中的建议,使用ConcurrentHashMap或并发库中的其他数据结构,而不是尝试使非并发数据结构线程安全的更困难的任务

一种解决方案是使用ConcurrentHashMap和ConcurrentLinkedQueue—无论何时向映射添加键值对,也将其键值添加到队列,并轮询队列以删除最旧的映射条目。一个潜在的复杂问题是,线程的交错将导致对象在添加到队列之前被添加到映射中——我不认为这是一个问题,因为您只需要队列的顺序来近似匹配键值对被添加到映射的顺序。


如果您希望能够在键值对过期之前从映射中移除它们,则此解决方案是有问题的,因为您可能需要遍历整个队列以移除已从映射中移除的键。此问题的最简单解决方案是,除非轮询,否则决不从队列中移除密钥,即如果从映射中移除一个键值对,则不从队列中移除密钥-队列中会有一些密钥与映射中的密钥不对应,但这只是一个问题,因为它会导致队列比需要的更大-地图的正确性不会受到影响。

我在这里有一个很长很复杂的答案,但后来我意识到这与说:

Map<K,V> myMap = Collections.<K,V>synchronizedMap(new LinkedHashMap<K,V>());

myMap现在是线程安全的LinkedHashMap。无需创建新类。

ConcurrentHashMap与HashMap类非常相似,只是ConcurrentHashMap提供内部维护的并发性。这意味着在多线程应用程序中访问ConcurrentHashMap时不需要同步块

//Initialize ConcurrentHashMap instance
ConcurrentHashMap<String, Integer> m = new ConcurrentHashMap<String, Integer>();

//Print all values stored in ConcurrentHashMap instance
for each (Entry<String, Integer> e : m.entrySet())
{
system.out.println(e.getKey()+"="+e.getValue());
}
上述代码在应用程序的多线程环境中合理有效。我所说的“合理有效”的原因是,上述代码虽然提供了线程安全性,但仍然会降低应用程序的性能。并引入ConcurrentHashMap以提高性能,同时确保线程安全

为了提高其性能,您可以根据需要调整以下参数:

初始容量 负荷系数 并发级别
线程安全性很难。使用ConcurrentHashMap。最好?它要么是线程安全的,要么不是线程安全的。通常有几种方法可以保证线程安全,有些方法比其他方法更好。Removeedestentiry函数让我很困惑。听起来它应该做些什么,但我看不出它做了什么:删除最老的条目。removeEldestEntry由LinkedHashMap impl自动调用并逐出缓存对象