fast多Map

du7egjpx  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(474)

我目前正在使用guava multimap实现。

map = Multimaps.synchronizedSetMultimap(HashMultimap.<K, R> create());

但是,我发现我的程序性能现在受到同步块的限制 synchronized (mutex) 用于 Multimaps.synchronizedSetMultimap .
因此,我正在寻找是否有任何替代品,以有一个同步的多重Map,这有望有助于提高多线程环境中的程序性能。
我不介意是否有额外的限制,比如只有一个线程用于更新(创建、修改或删除),只要我可以使用多个线程读取multimap数据,同时允许写操作。另外,对于我的项目使用,我主要是读取数据(如果时间大于99%),很少写入数据(小于1%),所以与读取性能相比,我不太在意写入性能)。
在高性能并发多Mapjava/scala中,有人建议使用

Multimaps.newSetMultimap(new ConcurrentHashMap<>(), ConcurrentHashMap::newKeySet)

由于我使用的是java 7,我将上述代码转换为:

map = Multimaps.newSetMultimap(new ConcurrentHashMap<K, Collection<R>>(), new Supplier<Set<R>>() {
    public Set<R> get() {
        return Sets.newSetFromMap(new ConcurrentHashMap<R, Boolean>());
    }
});

看起来效果很好。但从文件来看,它又指出了以下几点:
当任何并发操作更新multimap时,multimap都不是线程安全的,即使map和factory生成的示例都是线程安全的。并发读取操作将正常工作。要允许并发更新操作,请使用对synchronizedsetmultimap(com.google.common.collect.setmultimap<k,v>)的调用 Package multimap。
不过,我已经为并发读写创建了一个测试代码,它似乎可以工作(没有任何像concurrentmodificationexception这样的异常)。我当前的java版本是Java7,使用Guava14.0.1。
所以我的问题是,
如何在多线程环境中创建测试,以便 Multimaps.newSetMultimap(new ConcurrentHashMap<>(), ConcurrentHashMap::newKeySet) 不能正常工作?或者它只是偶然地与 ConcurrentHashMap ?
如果这行代码不适用于多线程环境,有人能给我建议一种方法来提高多线程处理中的多Map读取性能吗?
非常感谢。

slsn1g29

slsn1g291#

不过,我已经为并发读写创建了一个测试代码,它似乎可以工作(没有任何像concurrentmodificationexception这样的异常)。”
你不能真正测试线程安全性。线程安全性错误并不总是发生——它们只是偶尔发生,而且一旦发生就会非常混乱。
正如xaerxess在评论中所链接的那样,没有真正的方法来支持整个系统 Multimap 接口性能良好。解决方法不是使用multimap接口,而是拥有自己的接口 ConcurrentMap<K, Set<V>> 而且要非常非常小心(在Java7中,这将相当困难,限制更严格 ConcurrentMap 没有原子更新操作的接口。)

b0zn9rqh

b0zn9rqh2#

您可以使用:

ConcurrentMap<K, CopyOnWriteArraySet<V>> multimap = new ConcurrentHashMap<>();

您可以实现:

class ConcurrentArraySetMultimap<K, V> implements SetMultimap<K, V> {

最重要的是。
如果javadoc声明 Multimaps.newSetMultimap() 不是线程安全的,我不会试图证明它是错的。我看了一下实现,原因可能是附加的逻辑运行在 Map 以及 Set .

相关问题