【问题标题】:Thread-safe Multiset线程安全的多重集
【发布时间】:2014-09-06 09:24:27
【问题描述】:

我已经在谷歌上搜索了一段时间,不敢相信我找不到它,但是我怎样才能安全地实现一个 Multiset 将被多个线程访问以进行读取和写入。

multiset 将视图存储到某些页面,将是一个简单的Multiset<String>

旧版本的 Guava 在 Multisets 类中有一个 synchronizedMultiset 函数。我应该只使用自己的同步包装器吗?如果可用,我更愿意使用库版本。

【问题讨论】:

    标签: java multithreading thread-safety guava multiset


    【解决方案1】:

    根据Google Collection CodeMultiset只能使用方法执行线程安全

    synchronizedMultiset()
    

    此外,有必要用户在迭代其任何集合视图时手动同步返回的多重集

    虽然网上没有太多关于这个系列的信息

    【讨论】:

    【解决方案2】:

    使用ConcurrentHashMultiset

    This bug report 表示并发集合优于同步包装器,尽管这并不能解释为什么存在Multimaps.synchronizedMultimap

    【讨论】:

    • 还有see this issue
    • (任何想知道为什么Multimap 不同的人,请参阅this issue about concurrent Multimap implementations。)
    • @ChrisPovirk 是的,我实际上在不久前读过那个帖子并忘记了它。
    • 感谢您指出错误报告。可怕的部分是我只需要使用 Queues.synchronizedQueue() 来获得线程安全的 EvictingQueue,所以我在同一类中使用相反的观点(耶!?)。
    【解决方案3】:

    我认为从 Java 8 开始,您可以使用新方法 computeIfAbsent 轻松地将番石榴 Multiset 替换为 java.util.Map

    // Create new thread-safe 'multi set' using `java.util.Map`:
    Map<String, AtomicInteger> multiSet = new ConcurrentHashMap<>();
    
    // adding elements using computeIfAbsent:
    multiSet.computeIfAbsent("a", k -> new AtomicInteger()).incrementAndGet();
    multiSet.computeIfAbsent("a", k -> new AtomicInteger()).incrementAndGet();
    multiSet.computeIfAbsent("b", k -> new AtomicInteger()).incrementAndGet();
    
    // counting occurences:
    System.out.println(multiSet.get("a")); // prints '2'
    System.out.println(multiSet.get("b")); // prints '1'
    

    一般:

    public static <T> int add(Map<? super T, AtomicInteger> multiSet, T element) {
        return multiSet.computeIfAbsent(element, e -> new AtomicInteger()).incrementAndGet();
    }
    

    编写一个简化使用的瘦包装器应该很容易。

    【讨论】:

    • 感谢您的选择,但我认为使用 ConcurrentHashMultiset 我的代码看起来更清晰,并且我已经将 Guava 作为项目的核心库。
    • 当然。如果你已经在使用 Guava,ConcurrentHashMultiset 是最好的选择。我只是想指出,如果有人还没有使用它,它也可以在没有 Guava 的情况下轻松完成。
    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 2012-05-07
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    相关资源
    最近更新 更多