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