【问题标题】:Looking for concurrent map with functors寻找带有仿函数的并发映射
【发布时间】:2012-11-14 13:04:34
【问题描述】:


如果我查看 Java 中的 ConcurrentHashMap,
特别是 putIfAbsent 方法,该方法的典型用法是:

ConcurrentMap<String,Person>  map = new ConcurrentHashMap<>();
map.putIfAbsent("John",new Person("John"));

问题在于 Person 对象总是被初始化。
是否有一些帮助集合(可能是一些提供此功能的 java 框架)
这将为我提供与 ConcurrentHashMap 类似的行为,并且可以使用仿函数或任何其他方法来构造值对象,
并且仅当映射不包含给定键的值时才会调用构造代码(即 - functor.execute() )?

【问题讨论】:

  • 有趣的事实:Java 8 ConcurrentHashMap 将直接支持这一点。

标签: java multithreading concurrency java.util.concurrent


【解决方案1】:

做到这一点的唯一方法是使用锁定。您可以通过首先使用检查来最大程度地减少这种影响。

if(!map.containsKey("John"))
    synchronized(map) {
        if(!map.containsKey("John"))
           map.put("John", new Person("John"));
    }

您需要锁定的原因是您需要在创建 Person 时持有映射,以防止其他线程同时尝试添加相同的对象。 ConcurrentMap 不直接支持这样的阻塞操作。

如果您需要最小化对特定键的锁定,您可以执行以下操作。

ConcurrentMap<String, AtomicReference<Person>> map = new ConcurrentHashMap<String, AtomicReference<Person>>();

String name = "John";

AtomicReference<Person> personRef = map.get(name);
if (personRef == null)
    map.putIfAbsent(name, new AtomicReference<Person>());
personRef = map.get(name);
if (personRef.get() == null)
    synchronized (personRef) {
        if (personRef.get() == null)
            // can take a long time without blocking use of other keys.
            personRef.set(new Person(name));
    }
Person person = personRef.get();

【讨论】:

  • +1 用于原子引用和使用ConcurrentMap 接口。
猜你喜欢
  • 2015-08-24
  • 2013-06-28
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
相关资源
最近更新 更多