在不使用Collections.synchronizedMap的情况下,在外部实现linkedhashmap同步的最佳方法是什么
当使用Collections.synchronizedMap时,整个数据结构被锁定,因此性能受到严重影响。
仅锁定数据结构所需部分的最佳方法是什么。例如如果线程正在访问密钥(K1),它应该只锁定数据结构的Key(K1)和Value(v1)部分
答案 0 :(得分:3)
您无法从内置的Java实现中获得细粒度锁定的FIFO驱逐并发映射。
答案 1 :(得分:1)
我想你可能想要同步你所做的后续操作,只是来自地图的值:
Object value = map.get(key);
synchronized(value) {
doSomethingWith(value);
}
从Map获取值的同步是有意义的,因为它们可以同时共享和访问;我上面发布的示例应该做你需要的。那应该够了。
顺便说一下,您还可以在执行两个嵌套同步块的键上进行同步:
synchronized(key) {
Object value = map.get(key);
synchronized(value) {
doSomethingWith(value);
}
}
密钥 - 通常 - 仅用于访问对象(通过散列)。密钥与哈希值匹配,因此对我来说,通过密钥进行同步并不完全合理。
或者,也许您可以继承ConcurrentHashMap
,添加LinkedHashMap
中缺少的内容。
答案 2 :(得分:1)
Louis Wasserman的建议可能是最好的,因为它为您提供了许多有用的功能。但是,即使你锁定整个地图,你也必须真正地击中它,真的很难让它成为瓶颈(因为你的代码主要是在地图上进行读/写)。如果您不需要Guava Cache
的附加功能,则同步地图可能更简单&更好。如果您主要从地图上阅读,也可以使用ReadWriteLock
。
答案 3 :(得分:0)
如果您不需要LinkedHaspMap
,请使用ConcurrentHashMap
包中的java.util.concurrent
。
专为速度和螺纹安全而设计。它使用最小可能的锁定来实现其线程安全性。
答案 4 :(得分:0)
最佳选择是使用java.util.concurrent.ConcurrentHashMap
。
我看不出如何只能外部锁定zour Map的部分内容,因为你无法控制通过调用任何map函数在内部访问哪些共享数据结构。
答案 5 :(得分:0)
HashMap或LinkedHashMap中的插入可能会导致重新散列,因为它会增加大小和存储区数量之间的比率。让两个或多个线程同时重新进行同步将是一场灾难。
即使您只是在进行get,另一个线程可能正在从同一个存储桶中删除一个条目,因此您正在扫描正在修改的链接列表。您还可以同时将两个或多个线程附加到主链接列表。
如果没有链接,请使用java.util.concurrent.ConcurrentHashMap,如已建议的那样。