寻找与仿函数的并发地图

时间:2012-11-14 13:04:35

标签: java multithreading concurrency java.util.concurrent


如果我在java,和特别是putIfAbsent方法中查看ConcurrentHashMap,这种方法的典型用法是:

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

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

1 个答案:

答案 0 :(得分:2)

执行此操作的唯一方法是使用锁定。您可以先使用检查来最大限度地减少这种影响。

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();