Java的ConcurrentHashMap的模式 [英] Pattern for Java ConcurrentHashMap of Sets

查看:557
本文介绍了Java的ConcurrentHashMap的模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在多线程应用程序中常用的数据结构是ConcurrentHashMap,其中我要保存一组共享同一个键的项目。

A data structure that I use commonly in multi-threaded applications is a ConcurrentHashMap where I want to save a group of items that all share the same key. The problem occurs when installing the first item for a particular key value.

我一直在使用的模式是:

The pattern that I have been using is:

final ConcurrentMap<KEYTYPE, Set<VALUETYPE>> hashMap = new ConcurrentHashMap<KEYTYPE, Set<VALUETYPE>>();
// ...
Set<VALUETYPE> newSet = new HashSet<VALUETYPE>();
final Set<VALUETYPE> set = hashMap.putIfAbsent(key, newSet)
if (set != null) {
  newSet = set;
}
synchronized (newSet) {
  if (!newSet.contains(value)) {
    newSet.add(value);
  }
}

是否有更好的模式来执行此操作?这是线程安全吗?是否有更好的类用于内部 Set java.util.HashSet

Is there a better pattern for doing this operation? Is this even thread-safe? Is there a better class to use for the inner Set than java.util.HashSet?

推荐答案

我强烈建议您使用 Google Guava 库,特别是实施 Multimap HashMultimap 是你最好的选择,但如果你需要并发更新操作,你需要使用 Multimaps.synchronizedSetMultimap()

I strongly recommend using the Google Guava libraries for this, specifically an implementation of Multimap. The HashMultimap would be your best bet, though if you need concurrent update opterations you would need to wrap it in a delegate using Multimaps.synchronizedSetMultimap().

另一个选项是使用 ComputingMap (也来自Guava),这是一个映射,如果从调用 get(Key)不存在,它被实例化在那里。 ComputingMap 使用 MapMaker

Another option is to use a ComputingMap (also from Guava), which is a map that, if the Value returned from a call to get(Key) does not exist, it is instantiated there and then. ComputingMaps are created using MapMaker.

问题的代码大致如下:

ConcurrentMap<KEYTYPE, Set<VALUETYPE>> hashMap = new MapMaker()
                 .makeComputingMap(
        new Function<KEYTYPE, VALUETYPE>() {
         public Graph apply(KEYTYPE key) {
           return new HashSet<VALUETYPE>();
         }
       });

函数调用 get()为特定的键否则将返回null。这意味着你可以这样做:

The Function would only be called when a call to get() for a specific key would otherwise return null. This means that you can then do this:

hashMap.get(key).put(value);



<

safely knowing that the HashSet<VALUETYPE> is created if it doesn't already exist.

MapMaker 也是相关的,因为它给你的控制调整返回的Map,让您使用方法 concurrencyLevel()指定并发级别。您可能会发现有用的:

MapMaker is also relevant because of the control it gives you over the tuning of the returned Map, letting you specify, for example, the concurrency level using the method concurrencyLevel(). You may find that useful:


指导更新操作之间允许的并发性。用作内部尺寸的提示。该表在内部被分区以尝试允许指示数量的并发更新而没有争用。因为将条目分配给这些分区不一定是一致的,所以观察到的实际并发可能会有所不同。

Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The table is internally partitioned to try to permit the indicated number of concurrent updates without contention. Because assignment of entries to these partitions is not necessarily uniform, the actual concurrency observed may vary.

这篇关于Java的ConcurrentHashMap的模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆