java - 多线程环境中的快速 MultiMap

标签 java multithreading guava concurrenthashmap multimap

我目前正在使用 Guava Multimap执行。

map = Multimaps.synchronizedSetMultimap(HashMultimap.<K, R> create());
但是我发现我的程序性能现在受到同步块(synchronized block) synchronized (mutex) 的限制。用于Multimaps.synchronizedSetMultimap .
因此,我正在寻找是否有任何替代方案可以使用同步多映射,这有望有助于提高多线程环境中的程序性能。
我不介意是否施加额外的限制,比如只有一个线程用于更新(创建、修改或删除),只要我可以使用多个线程读取多图数据并同时允许写入操作。另外,对于我的项目使用来说,我主要是读取数据(如果时间>99%),很少写入数据(<1%),因此与读取性能相比,我不太关心写入性能)。

来自 High-performance Concurrent MultiMap Java/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>());
    }
});
这似乎工作得很好。但再次来自 documentation ,它声明如下:

The multimap is not threadsafe when any concurrent operations update the multimap, even if map and the instances generated by factory are. Concurrent read operations will work correctly. To allow concurrent update operations, wrap the multimap with a call to synchronizedSetMultimap(com.google.common.collect.SetMultimap<K, V>).


但是我已经为并发读写创建了一个测试代码,它似乎可以工作(没有任何异常,如 ConcurrentModificationException)。我当前的 Java 版本是 Java 7 并使用 Guava 14.0.1。
所以我的问题是,
  • 如何在多线程环境中创建测试,这样 Multimaps.newSetMultimap(new ConcurrentHashMap<>(), ConcurrentHashMap::newKeySet)无法正常工作?或者它只是偶然地与 ConcurrentHashMap 一起工作。 ?
  • 如果这行代码不适用于多线程环境,任何人都可以建议我在多线程处理中提高多映射读取性能的方法吗?

  • 非常感谢。

    最佳答案

    你可以使用:

    ConcurrentMap<K, CopyOnWriteArraySet<V>> multimap = new ConcurrentHashMap<>();
    
    你可以实现:
    class ConcurrentArraySetMultimap<K, V> implements SetMultimap<K, V> {
    
    在它的上面。

    如果 Javadoc 声明 Multimaps.newSetMultimap()不是线程安全的,我不会试图证明它是错误的。我查看了实现,原因可能是附加逻辑运行在修饰的 Map 之上。和 Set .

    关于java - 多线程环境中的快速 MultiMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65319282/

    相关文章:

    java - 如何用java编写监控软件

    c++ - 使用两个线程和 boolean 值的奇怪问题

    java - Guava future 等待回调

    java - 将 map 转换为排序列表

    java - Apache Camel Ftp2 下载文件的顺序

    java - java中的录音机问题

    multithreading - 在 Intellij Idea 中的线程之间切换

    java - Android游戏开发-BOT玩家线程的使用和AndEngine配置

    java - 如何将值映射回枚举?

    java - 将输入 JSON 中的键和值转换为 Guava ListMultimap?