3


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

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

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

4

1 回答 1

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();
于 2012-11-14T13:08:11.860 回答